畅通工程[HDU1863]

畅通工程

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 27097 Accepted Submission(s): 11840


Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。

Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。

Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100

Sample Output
3
?

Source
浙大计算机研究生复试上机考试-2007年

#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;
class Union_Find_Set {
#define MAX_UNION_FIND_SET_SIZE 105
public:
    int setSize;
    int father[MAX_UNION_FIND_SET_SIZE];
    Union_Find_Set() {
        setSize = 0;
    }
    Union_Find_Set(int x) {
        setSize = x;
        clear(x);
    }
    void clear(int x) {
        for (int i = 0; i < x; i++) {
            father[i] = i;
        }
    }
    int getFather(int x) {
        if (x != father[x]) {
            father[x] = getFather(father[x]);
        }
        return father[x];
    }
    bool merge(int a, int b) {
        a = getFather(a);
        b = getFather(b);
        if (a != b) {
            father[a] = b;
            return true;
        } else {
            return false;
        }
    }
    int countRoot() {
        int ret = 0;
        for (int i = 0; i < setSize; i++) {
            if (father[i] = i) {
                ret++;
            }
        }
        return ret;
    }
};
class Kruskal {
#define Kruskal_MAXN 100
#define Kruskal_MAXM 10005
public:
    Union_Find_Set ufs;
    int x[Kruskal_MAXM], y[Kruskal_MAXM], w[Kruskal_MAXM], N, M;
    Kruskal() {
        N = 0;
        M = 0;
    }
    void clear() {
        N = 0;
        M = 0;
    }
    void addEdge(int a, int b, int c) {
        x[M] = a;
        y[M] = b;
        w[M] = c;
        M++;
        x[M] = b;
        y[M] = a;
        w[M] = c;
        M++;
    }
    void sort(int l, int r) {
        int i = l, j = r, m = w[(l + r) >> 1], t;
        do {
            while (w[i] < m) {
                i++;
            }
            while (m < w[j]) {
                j--;
            }
            if (i <= j) {
                t = x[i];
                x[i] = x[j];
                x[j] = t;
                t = y[i];
                y[i] = y[j];
                y[j] = t;
                t = w[i];
                w[i] = w[j];
                w[j] = t;
                i++;
                j--;
            }
        } while (i <= j);
        if (l < j) {
            sort(l, j);
        }
        if (i < r) {
            sort(i, r);
        }
    }
    int MST() {
        sort(0, M - 1);
        ufs.clear(N + 1);
        int cnt = 0, ret = 0;
        for (int i = 0; i < M; i++) {
            if (cnt == N - 1) {
                return ret;
            }
            if (ufs.getFather(x[i]) != ufs.getFather(y[i])) {
                ufs.merge(x[i], y[i]);
                ret += w[i];
                cnt++;
            }
        }
        if (cnt == N - 1) {
            return ret;
        } else {
            return -1;
        }
    }
};
Kruskal Kr;
int main() {
    int n, m;
    while (scanf("%d%d", &m, &n) != EOF) {
        if (m == 0) {
            break;
        }
        Kr.clear();
        Kr.N = n;
        for (int i = 0; i < m; i++) {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            Kr.addEdge(a, b, c);
        }
        int ans = Kr.MST();
        if (ans == -1) {
            printf("?
");
        } else {
            printf("%d
", ans);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/dramstadt/p/6207143.html