zoukankan      html  css  js  c++  java
  • 畅通工程[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
  • 相关阅读:
    SQL Server 附加数据库,报只读文件,无权修改其中某些文件
    NLog.config 配置
    系统架构设计师论文可靠性设计
    二、软件设计原则
    JavaScript 判断数组是否含有重复值
    mysql 添加索引 mysql 如何创建和删除索引
    利用pandas,BytesIO,zipfile打包csv文件,生成压缩文件
    不良人mysql索引
    转mysql数据库允许空值索引问题
    多线程中ThreadPoolExecutor.map()中传递多个参数
  • 原文地址:https://www.cnblogs.com/dramstadt/p/6207143.html
Copyright © 2011-2022 走看看