还是畅通工程+流通图=畅通工程
#include <stdio.h> typedef struct Edge{ int from,to,len; }Edge; Edge e[10000]; int dad[100],h[100]; void Initial(int n) { for(int i=0;i<=n;i++) { dad[i]=i; h[i]=0; } } int Find(int x) { if(x!=dad[x]) dad[x]=Find(dad[x]); return dad[x]; } void Union(int x,int y) { x = Find(x); y = Find(y); if(x!=y) { if(h[x]<h[y]) dad[x]=y; else if(h[x]>h[y]) dad[y]=x; else{ dad[y]=x; h[x]++; } } return; } int cmp(const void *a,const void *b) { return (*(Edge*)a).len-(*(Edge*)b).len; } int Kruskal(int n,int num) { Initial(n); qsort(e,num,sizeof(e[0]),cmp); int sum = 0; for(int i=0;i<num;i++) { if(Find(e[i].from)!=Find(e[i].to)) { Union(e[i].from, e[i].to); sum+=e[i].len; } } return sum; } int main() { int n,m,ans,i,b; while(scanf("%d %d",&n,&m)!=EOF) { if(n==0) break; for(i=0;i<n;i++) { scanf("%d %d %d",&e[i].from,&e[i].to,&e[i].len); } ans=Kruskal(m, n); b=0; for(i=1;i<=n;i++) { if(Find(i)==i) b++; } if(b==1&&n>=m-1) printf("%d\n",ans); else printf("?\n"); } return 0; }