• HDU1233 还是畅通工程


    问题链接:HDU1233 还是畅通工程

    问题描述:参见上述链接

    问题分析:这是一个最小生成树的为问题,解决的算法有Kruskal(克鲁斯卡尔)算法和Prim(普里姆)算法

    程序说明:本程序使用Kruskal算法实现。有关最小生成树的问题,使用克鲁斯卡尔算法更具有优势,只需要对所有的边进行排序后处理一遍即可。程序中使用了并查集,用来判定加入一条边后会不会产生循环。程序中,图采用边列表的方式存储,按边的权从小到大顺序放在优先队列中,省去了排序。

    需要注意的是,优先队列申明的位置,以及它和结束条件(“count == n - 1”)的配合。对于每一个测试用例,开始是优先队列应该是空的。

    AC的C++语言程序如下:

    /* HDU1233 还是畅通工程 */
    
    #include <iostream>
    #include <queue>
    #include <cstdio>
    
    using namespace std;
    
    const int MAXN = 100;
    
    // 并查集
    int v[MAXN+1];
    class UF {
        int length;
    public:
        UF() {}
    
        // 压缩
        int Find(int x) {
            if(x == v[x])
                return x;
            else
                return v[x] = Find(v[x]);
        }
    
        bool Union(int x, int y) {
            x = Find(x);
            y = Find(y);
            if(x == y)
                return false;
            else {
                v[x] = y;
                return true;
            }
        }
    
        // 唯一树根判定连通性
        bool isconnect() {
            int root = -1;
            for( int i=1 ; i<=length ; i++ )
                if(root == -1)
                   root = Find(i);
                else
                    if(Find(i) != root)
                        return false;
    
            return true;
        }
    
        void reset(int n) {
            length = n;
            for(int i=0; i<=n; i++)
                v[i] = i;
        }
    };
    
    struct edge {
        int src, dest, cost;
        bool operator < (const edge& n) const {
            return cost > n.cost;
        }
    };
    
    int main()
    {
        UF uf;
        edge e;
        int n, m;
    
        while(scanf("%d", &n) != EOF && n) {
            priority_queue<edge> q;     // 优先队列,用于存储边列表
    
            uf.reset(n);
    
            m = n * (n-1) / 2;
    
            // 构建优先队列
            while(m--) {
                scanf("%d%d%d", &e.src, &e.dest, &e.cost);
                q.push(e);
            }
    
            // Kruskal算法:获得最小生成树
            int ans=0, count=0;
            while(!q.empty()) {
                e = q.top();
                q.pop();
    
                if(uf.Union(e.src, e.dest)) {
                    count++;
                    ans += e.cost;
                }
    
                if(count == n - 1)
                    break;
            }
    
            // 结果
            printf("%d
    ", ans);
        }
    
        return 0;
    }



  • 相关阅读:
    win10-wifi无线共享自动关闭解决
    可用的nlog配置
    cmake 常用指令,变量
    window时间服务
    命令行配置服务启动类型
    boost流gzip压缩
    mysql 查询某表的所有列,获取毫秒时间戳
    system进程占用80端口
    centos8重新分区(减小/home空间,增大root空间)
    emqx使用data_to_webservice方式配置规则引擎简单实践
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564089.html
Copyright © 2020-2023  润新知