这题是最小生成树,克鲁斯卡尔(Kruskal)算法,不过也就是并查集加了个排序而已,并查集懂了,这就是小菜,不过排序要用sort()函数或者快排,用冒泡超时,坑了我好久。。。
还是畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 19523 Accepted Submission(s): 8685
当N为0时,输入结束,该用例不被处理。
3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0
3 5
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int father[101]; struct node { int begin; int end; int weight; } edge[5001];
bool cmp(const node &a,const node &b) { return a.weight<b.weight; }
int find(int r) { while(father[r]!=r) r=father[r]; return r; }
int main() { int n,i,j,m,sum,x,y; while(cin>>n&&n) { sum=0; m=(n*(n-1))/2; for(i=0;i<=n;i++) { father[i]=i; } for(i=0; i<m; i++) { scanf("%d%d%d",&edge[i].begin,&edge[i].end,&edge[i].weight); } sort(edge,edge+m,cmp); for(i=0,j=0;i<m;i++) { if(j==n-1) break; x=find(edge[i].begin); y=find(edge[i].end); if(x!=y) { father[x]=y; sum+=edge[i].weight; j++; } } cout<<sum<<endl; }
}