MST的简单变形。当一个边的长度为零时,那么就假定这两个点已经在一个集合中了,剩下的步骤和普通kruskal是一样的。 #include<stdio.h> #include<string.h> #include<stdlib.h> int p[500]; int find(int i) {return i==p[i]?i:(p[i]=find(p[i]));} struct edge { int from,to,w; } a[250000],t; int cmp(const void *a,const void *b) { return ((struct edge *)a)->w > ((struct edge *)b)->w; } int main(void) { int cases,n,m; int i,from,to; int k,sum,count; scanf("%d",&cases); while( cases-- ) { scanf("%d%d",&n,&m); for( k = 0; k < n; k++ ) p[k] = k; for( k = 0,count = 0; k < m; k++ ) { scanf("%d%d%d",&t.from,&t.to,&t.w); if( t.w == 0 ) { p[ find(t.from) ] = find(t.to); continue; } a[count++] = t; } qsort(a,count,sizeof(a[0]),cmp); for( i = 0,sum = 0; i < count; i++) { from = find( a[i].from ); to = find( a[i].to ); if( from == to ) continue; p[from] = to; sum += a[i].w; } printf("%d/n",sum); } return 0; }