2024牛客暑期多校训练营2 B MST

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

Sajin has recently delved into the study of minimum spanning trees and now he has mastered the algorithm of MST.

He is eager to assess your grasp of minimum spanning tree concepts through a series of queries.

You are confronted with an weighted undirected graph that encompasses nnn vertices and mmm edges without any self-loops.

Sajin presents qqq inquiries. For each, a vertex set S is given. Your objective is to determine the induced subgraph of S and find the weight of its minimum spanning tree.

A minimum spanning tree (MST) is a subset of the edges of a connected, edge-weighted graph that connects all the vertices together without any cycles and with the minimum possible total edge weight.

In the mathematical field of graph theory, an induced subgraph of a graph is another graph, formed from a subset of the vertices of the graph and all of the edges, from the original graph, connecting pairs of vertices in that subset.

If the induced subgraph of S is disconnected, output -1.

输入描述:

The first line contains 333 integers n, m, q (2≤n≤1e5,1≤m,q≤1e5 ), — the number of points, the number of edges, and the number of queries.

Then m lines follow, each line contains three integers u​, v​, w​(1≤ui,vi≤n,1≤wi​≤1e9), — the two endpoints of the iii-th edge and the edge weight.

Next q lines, each line first contains an integer ki(1≤ki≤n) — the size of the vertex set S for the iii-th query.

Then followed by ki distinct integers si,j​(1≤si,j≤n) — the numbers of the vertex set S for the iii-th query.


It is guaranteed that the sum of ki over all queries does not exceed 1e5.

输出描述:

For each query, output one integer representing the answer.

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

输入

复制5 10 5 1 2 1 1 3 1 1 4 1 1 5 1 2 3 2 2 4 2 2 5 2 3 4 3 3 5 3 4 5 4 5 1 2 3 4 5 4 2 3 4 5 3 3 4 5 2 4 5 1 5

5 10 5
1 2 1
1 3 1
1 4 1
1 5 1
2 3 2
2 4 2
2 5 2
3 4 3
3 5 3
4 5 4
5 1 2 3 4 5
4 2 3 4 5
3 3 4 5
2 4 5
1 5

输出

复制4 6 6 4 0

4
6
6
4
0

示例2

输入

复制3 2 1 1 2 1 2 3 1 2 1 3

3 2 1
1 2 1
2 3 1
2 1 3

输出

复制​​​​​​​-1

-1

题意

有n个点,m条边,q此询问。

对于每次询问,输出连接给出的k个点所需的代价为多少。

思路

用最小生成数,求连接给出的k个点所需的最小代价。

​
​
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define pii pair<int,int>
using namespace std;
const int N=1e6+10;
int fa[2*N],vis[2*N];
map<pii,int> mp;
vector<int> a;
struct node{
	int u,v,w;
}s[2*N],e[2*N];
bool cmp(node x,node y){
	return x.w<y.w;
}
int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
signed main()
{
	int n,m,q;
	cin>>n>>m>>q;
	//存图 
	for(int i=1;i<=m;i++){
		cin>>s[i].u>>s[i].v>>s[i].w;
		if(mp[{s[i].u,s[i].v}]==0)mp[{s[i].u,s[i].v}]=s[i].w;
		else mp[{s[i].u,s[i].v}]=min(mp[{s[i].u,s[i].v}],s[i].w);
			
	}
	sort(s+1,s+m+1,cmp);
	while(q--){
		a.clear();//清空 
		int k;
		cin>>k;
		int cnt=0;
		for(int i=0;i<k;i++){
			int x;
			cin>>x;
			a.push_back(x);
			fa[x]=x;//初始化父节点的指向 
		}
		if(k<sqrt(n)){
            //寻找边是否存在 
			for(int i=0;i<k;i++){
				for(int j=0;j<k;j++){
					if(mp.count({a[i],a[j]})){
						e[++cnt]={a[i],a[j],mp[{a[i],a[j]}]};
					}
				}
			}
		}
		else{
			for(auto it:a){
				vis[it]=1;
			}
			for(int i=1;i<=m;i++){
				if(vis[s[i].u]&&vis[s[i].v])e[++cnt]=s[i];
			}
		}
		sort(e+1,e+1+cnt,cmp);
		int ans=0,sum=0;
		for(int i=1;i<=cnt;i++){
			if(find(e[i].u)!=find(e[i].v)){
				fa[find(e[i].u)]=find(e[i].v);
				ans+=e[i].w;
				sum++;
			}
			if(sum>=k-1)break;
		}
		if(sum<k-1) cout<<-1<<endl;
		else cout<<ans<<endl;
        //使标记数组还原
		for(auto it:a){
			vis[it]=0;
		}
	}
	return 0;
}

​

​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值