http://acm.hdu.edu.cn/showproblem.php?pid=1879
克鲁斯卡尔算法求解最小生成树(MST)
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int father[110],n,m;
struct node{
int from,to,cost;
}edge[5010];
void Init(){
for(int i=1; i<=n; i++)
father[i] = i;
}
int Find(int x){
if(x == father[x]) return x;
return Find(father[x]);
}
void Union(int fx, int fy){
father[fy] = fx;
}
bool cmp(const node &A, const node &B){
return A.cost < B.cost;
}
int main(){
// freopen("in.txt", "r", stdin);
while(scanf("%d",&n) == 1 && n){
Init();
m = n*(n-1)/2;
int from,to,cost,key;
for(int i=0; i<m; i++){
scanf("%d%d%d%d",&from,&to,&cost,&key);
edge[i].from = from,edge[i].to = to;
if(key) edge[i].cost = 0;
else edge[i].cost = cost;
}
sort(edge, edge+m, cmp);///将边按照权值大小排序
int cnt = n, ans = 0;
for(int i=0; i<m && cnt > 1; i++){///cnt = 1代表已经找到一棵最小生成树
int fx = Find(edge[i].from), fy = Find(edge[i].to);
if(fx != fy){
Union(fx, fy);
cnt--;
ans += edge[i].cost;
}
}
printf("%d\n",ans);
}
return 0;
}