链接:登录—专业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;
}