题意: 给你n个城市让你花最小代价连起来,但是给你了几个已经连好的城市。
我上来怼了一发prim 超时,我就想,kruskal 应该可以,最后没时间敲,,,gg
直接kruskal 模板就能过。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int inf=0xffffff;
const int maxn=505;
struct node{
int u,v,w;
bool operator <(const node &a)const{
return w<a.w;
}
}edge[maxn*maxn];
int n,m,w,T,cnt,t;
int fa[maxn];
int dis[maxn];
void addedge(int x,int y,int val){
edge[++cnt].u=x;
edge[cnt].v=y;
edge[cnt].w=val;
}
int Find(int x){
if(fa[x]==-1) return x;
return fa[x]=Find(fa[x]);
}
int kruskal(int n){
int ans=0;
for(int i=1;i<=cnt;++i){
int u=edge[i].u;
int v=edge[i].v;
int w=edge[i].w;
int t1=Find(u);
int t2=Find(v);
if(t1!=t2){
ans+=w;
fa[t1]=t2;
t++;
}
if(t==n) break;
}
if(t<n) return -1;
else return ans;
}
int main(){
int a,b,c,q;
scanf("%d",&T);
while(T--){
cnt=0;t=1;
memset(fa,-1,sizeof(fa));
scanf("%d %d %d",&n,&m,&w);
while(m--){
scanf("%d %d %d",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
sort(edge+1,edge+1+cnt);
while(w--){
scanf("%d",&q);
for(int i=0;i<q;++i){
scanf("%d",&a);
if(!i) b=a;
else {
int t1=Find(a),t2=Find(b);
if(t1!=t2) fa[t1]=t2,t++;
b=a;
}
}
}
int ans=kruskal(n);
printf("%d\n",ans);
}
return 0;
}