【解题报告】 HDU 1879 继续畅通工程 并查集 + 贪心

题目连接: 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;
}

你可能感兴趣的:(struct,测试)