zoukankan      html  css  js  c++  java
  • 1350:【例411】最短网络(agrinet)

    【题目描述】

    农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000100000。

    【输入】

    第一行:农场的个数,N3N100N(3≤N≤100)。

    第二行..结尾:后来的行包含了一个N×NN×N的矩阵,表示每个农场之间的距离。理论上,他们是NN行,每行由NN个用空格分隔的数组成,实际上,他们限制在8080个字符,因此,某些行会紧接着另一些行。当然,对角线将会是00,因为不会有线路从第ii个农场到它本身。

    【输出】

    只有一个输出,其中包含连接到每个农场的光纤的最小长度。

    【输入样例】

    4
    0 4 9 21
    4 0 8 17
    9 8 0 16
    21 17 16 0

    【输出样例】

    28

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Node { // 边[x,y]权重w
        int x, y, w;
    
        Node(int x, int y, int w)
        {
            this->x = x;
            this->y = y;
            this->w = w;
        }
    };
    
    bool cmp(const Node &a, const Node &b)
    { // 边的比较,小的在前
        return (a.w < b.w);
    }
    
    void init(vector<int> &da)
    { // 并查集的初始化
        for (int i = 0; i < da.size(); i++) {
            da[i] = i;
        }
    }
    
    int find(vector<int> &da, int x)
    { // 并查集的查找
        if (da[x] != x) {
            da[x] = find(da, da[x]);
        }
        return da[x];
    }
    
    bool united(vector<int> &da, int x, int y)
    { // 并查集的判断
        int xda = find(da, x);
        int yda = find(da, y);
        return (xda == yda);
    }
    
    void unite(vector<int> &da, int x, int y)
    { // 并查集的合并
        int xda = find(da, x);
        int yda = find(da, y);
        if (xda != yda) {
            da[xda] = yda;
        }
    }
    
    int kruskal(vector<Node> &es, int n)
    { // 克鲁斯卡尔算法
        int ans = 0; // 答案
        vector<int> da(n + 1); // 并查集
        init(da); // 初始化并查集
        sort(es.begin(), es.end(), cmp);
        for (auto &e : es) { // 遍历所有边
            if (united(da, e.x, e.y)) {
                continue; // 能形成环
            }
            // cout << e.x << "," << e.y << endl;
            unite(da, e.x, e.y);
            ans += e.w;
        }
        return ans;
    }
    
    int main()
    {
        // freopen("in.txt", "r", stdin);
        int n, w; // 节点数n, 权重w
        scanf("%d", &n);
        vector<Node> es; // 边集
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf("%d%", &w);
                if (w > 0 && i < j) { // 非0
                    es.push_back(Node(i, j, w));
                }
            }
        }
        int ans = kruskal(es, n);
        printf("%d\n", ans);
        return 0;
    }
    

      

  • 相关阅读:
    PAT B1027 打印沙漏 (20 分)
    PAT B1025 反转链表 (25 分)
    PAT B1022 D进制的A+B (20 分)
    PAT B1018 锤子剪刀布 (20 分)
    PAT B1017 A除以B (20 分)
    PAT B1015 德才论 (25 分)
    PAT B1013 数素数 (20 分)
    PAT B1010 一元多项式求导 (25 分)
    HDU 1405 The Last Practice
    HDU 1165 Eddy's research II
  • 原文地址:https://www.cnblogs.com/gaojs/p/15584358.html
Copyright © 2011-2022 走看看