Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7338 Accepted Submission(s): 2093
#include <iostream> #include <cstdlib> #include<algorithm> using namespace std; int father[560],Q; struct sum { int a; int b; int c; }num[50005]; //路线数 bool cmp(const sum &x,const sum &y) //按长度从小到大快排, { return x.c<y.c;//原理有待研究 } int Find(int x) //找出祖先 { while(x!=father[x]) x=father[x]; return x; } void Union(int a,int b,int i) { if(a!=b) { father[a]=b; Q+=num[i].c; //并入家族且把长度加上来 } } int main() { int T,k,n,m,i,j,l,p,q,c,t; int ss[505]; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); for(i=1;i<=n;i++) father[i]=i; for(i=0;i<m;i++) scanf("%d%d%d",&num[i].a,&num[i].b,&num[i].c); memset(ss,0,sizeof(ss)); for(l=0;l<k;l++) { scanf("%d",&t); for(j=0;j<t;j++) scanf("%d",&ss[j]); for(j=1;j<t;j++) { if(Find(ss[0])!=Find(ss[j])) father[Find(ss[j])]=Find(ss[0]); } memset(ss,0,sizeof(ss)); } sort(num,num+m,cmp);//排序 for(i=0,Q=0;i<m;i++) { Union(Find(num[i].a),Find(num[i].b),i); } for(i=1,t=0;t<2&&i<=n;i++) if(father[i]==i) t++; if(t==2) printf("-1\n"); else printf("%d\n",Q); } return 0; } /* 5 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 1 3 3 4 5 6 6 4 3 1 4 3 2 6 2 6 2 1 3 4 33 2 1 2 2 1 3 3 4 5 6 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 2 3 2 4 5 6 4 3 1 4 3 2 6 2 6 2 1 3 4 33 2 1 2 2 1 3 2 4 6*/
在网上找了Kruskal函数, 有待学习!
#include<stdio.h> //Kruskal函数 #include<algorithm> using namespace std; typedef struct{ int u; int v; int w; }Edge; const int EdgeNum=50010; const int PointNum=510; Edge E[EdgeNum]; int P[PointNum]; int union_find(int x) // 并查集 { return P[x]==x? x : P[x]=union_find(P[x]); } bool cmp(Edge a,Edge b){ return a.w<b.w; } int MST_Kruskal(int n,int m) // 传入点数和边数 { int i,j,x,y,k=1,sum=0; for(i=0;i<n;++i) { for(j=0;j<n;++j) { if(i==j) continue; if(P[j]==i) { k++; // printf("P[%d]=%d\n",j,i); } } } // printf("k=%d\n",k); sort(E,E+m,cmp); for(i=0;k<n&&i<m;++i) { x=union_find(E[i].u); y=union_find(E[i].v); if(x!=y) { sum+=E[i].w; P[x]=y; k++; } } if(k<n) return -1; return sum; } int f[510]; int solve(int n,int m,int k) { int i,j,t; for(i=0;i<n;++i) { // 初始化并查集 P[i]=i; } for(i=0;i<k;++i){ scanf("%d",&t); for(j=0;j<t;++j) { scanf("%d",&f[j]); f[j]--; } for(j=1;j<t;++j) P[union_find(f[j])]=union_find(f[j-1]); } return MST_Kruskal(n,m); } int main() { int t,n,m,k,i,p,q,c,ans; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(i=0;i<m;++i) { scanf("%d%d%d",&p,&q,&c); p--;q--; E[i].u=p;E[i].v=q;E[i].w=c; } ans=solve(n,m,k); printf("%d\n",ans); } return 0; }