用Kruskal算法求最小生成树,要用到并查集,最后再顺便用并查集判断是否连通,只需判断父节点数是否唯一
#include<iostream> #include<string> #define MAXN 101 using namespace std; int n,m,f[MAXN],ans; struct edge { int u,v,w; edge(int x=0,int y=0,int z=0):u(x),v(y),w(z){}; }e[MAXN*50]; int cmp(const void *a, const void *b) { if(((struct edge *)a)->w!=((struct edge *)b)->w) { return ((struct edge *)a)->w-((struct edge *)b)->w; } else { return ((struct edge *)a)->u-((struct edge *)b)->u; } } void init() { for(int i=0;i<=n;i++) f[i]=i; } int find(int x) { if(x==f[x]) return x; f[x]=find(f[x]); return f[x]; } void Union(int x,int y,int c) { int a=find(x); int b=find(y); if(a==b) return ; f[b]=a; ans+=c; } int main() { int a,b,c; while(scanf("%d %d",&m,&n)==2&&m) { int num=0; for(int i=0;i<m;i++) { scanf("%d %d %d",&a,&b,&c); e[num++]=edge(a,b,c); } qsort(e,num,sizeof(e[0]),cmp); init(); ans=0; for(int i=0;i<num;i++) Union(e[i].u,e[i].v,e[i].w); int cou=0; for(int i=1;i<=n;i++) if(find(i)==i) cou++; if(cou>1) printf("?\n"); else printf("%d\n",ans); } return 0; }