题目连接: HDU 1879
题目大意:略
// HDU 1879 继续畅通工程
// 并查集 + 贪心
// 每个测试用例的第1行给出村庄数目N ( 1< N < 100 );
// 随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,
// 分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,
// 以及修建状态:1表示已建,0表示未建。
// 求最少的成本使得全部村庄连通
/*test data
3
1 2 1 0
1 3 2 0
2 3 4 0 =3
3
1 2 1 0
1 3 2 0
2 3 4 1 =1
3
1 2 1 0
1 3 2 1
2 3 4 1 =0
1
1 1 0 0 =0
2
1 2 1 0 =1
0
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXV = 101;
int father[MAXV];
int num[MAXV];
struct Via{
int a,b,cost;
}via[MAXV*MAXV];
int find(int x){
if (father[x] == x)return x;
return father[x] = find(father[x]);
}
void combination(int a,int b){
father[b] = a;
num[a] += num[b];
}
bool com(Via a,Via b){
return a.cost < b.cost;
}
void MST(int ncity,int k){
int res=0;
for (int i = 1 ; i <= k; i++){
int ra = find(via[i].a);
int rb = find(via[i].b);
if (ra != rb){
combination(ra,rb);
res += via[i].cost;
}
}
cout << res << endl;
}
int main()
{
// freopen("in.txt","r",stdin);
int ncity;
while(scanf("%d",&ncity),ncity){
// nvia表示所有的道路数,sit表示道路状态 1为修过的,0为木有修过的
int a,b,cost,sit,nvia = (ncity * (ncity - 1)) / 2;
if (ncity==1) nvia=1; // only one city
for (int i = 0; i < MAXV ; i++){num[i]=1;father[i]=i;}
for (int i = 1; i <= nvia; i++){
scanf("%d %d %d %d",&a,&b,&cost,&sit);
if (sit) cost = 0;
via[i].a = a;
via[i].b = b;
via[i].cost = cost;
}
sort(&via[1],&via[nvia+1],com);
MST(ncity,nvia);
}
return 0;
}