最小生成树的题。我用的克鲁斯卡尔算法。

1 #include <stdio.h> 2 #define N 100 3 #define M 5000 4 struct node 5 { 6 int a,b,d; 7 }edge[M]; 8 int n,m; 9 int p[N]; 10 void make_set() 11 { 12 int i; 13 for(i=1;i<=n;i++) p[i]=i; 14 } 15 int find_set(int i) 16 { 17 return i==p[i]?p[i]:(p[i]=find_set(p[i])); 18 } 19 void union_set(int i,int j) 20 { 21 p[j]=i; 22 } 23 int cmp(const void *a,const void *b) 24 { 25 return ((struct node*)a)->d-((struct node*)b)->d; 26 } 27 int main() 28 { 29 int i,ans,cnt; 30 while(scanf("%d%d",&m,&n)&&m) 31 { 32 for(i=0;i<m;i++) scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].d); 33 ans=cnt=0; 34 make_set(); 35 qsort(edge,m,sizeof(edge[0]),cmp); 36 for(i=0;cnt<n-1&&i<m;i++) 37 { 38 if(find_set(edge[i].a)==find_set(edge[i].b)) continue; 39 ans+=edge[i].d; 40 union_set(edge[i].a,edge[i].b); 41 cnt++; 42 } 43 if(cnt==n-1) printf("%d\n",ans); 44 else printf("?\n"); 45 } 46 return 0; 47 }