• acwing算法提高之图论--最小生成树的典型应用


    1 介绍

    本专题用来记录使用prim算法或kruskal算法求解的题目。

    2 训练

    题目11140最短网络

    C++代码如下,

    #include 
    #include 
    
    using namespace std;
    
    const int N = 110, INF = 0x3f3f3f3f;
    int g[N][N];
    int d[N];
    bool st[N];
    int n, m;
    
    void prim() {
        memset(d, 0x3f, sizeof d);
        
        int res = 0;
        for (int i = 0; i < n; ++i) {
            int t = -1;
            for (int j = 1; j <= n; ++j) {
                if (!st[j] && (t == -1 || d[t] > d[j])) {
                    t = j;
                }
            }
            
            st[t] = true;
            if (i) res += d[t];
            
            for (int j = 1; j <= n; ++j) {
                if (d[j] > g[t][j]) {
                    d[j] = g[t][j];
                }
            }
        }
        
        cout << res << endl;
        return;
    }
    
    int main() {
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                cin >> g[i][j];
            }
        }
        
        prim();
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    题目21141局域网

    C++代码如下,

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 110, M = 210;
    int p[N];
    int n, m;
    
    struct Edge {
        int a, b, w;
        bool operator< (const Edge &W) const {
            return w < W.w;
        }
    }edges[M];
    
    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int main() {
        cin >> n >> m;
        int s = 0;
        for (int i = 0; i < m; ++i) {
            cin >> edges[i].a >> edges[i].b >> edges[i].w;
            s += edges[i].w;
        }
        
        for (int i = 1; i <= n; ++i) p[i] = i;
        
        sort(edges, edges + m);
        
        int res = 0, cnt = 0;
        for (int i = 0; i < m; ++i) {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a);
            b = find(b);
            if (a != b) {
                p[a] = b;
                res += w;
                cnt++;
            }
        }
        
        cout << s - res << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    题目31142繁忙的都市

    C++代码如下,

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 310, M = 8010;
    int n, m;
    int p[N];
    
    struct Edge {
        int a, b, w;
        bool operator< (const Edge &W) const {
            return w < W.w;
        }
    }edges[M];
    
    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) p[i] = i;
        
        for (int i = 0; i < m; ++i) {
            cin >> edges[i].a >> edges[i].b >> edges[i].w;
        }
        
        sort(edges, edges + m);
        
        int res = 0;
        int cnt = 0;
        for (int i = 0; i < m; ++i) {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a);
            b = find(b);
            if (a != b) {
                p[a] = b;
                cnt += 1;
                res = w;
            }
        }
        
        cout << cnt << " " << res << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    题目41143联络员

    C++代码如下,

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 2010, M = 10010;
    int n, m;
    int p[N];
    struct Edge {
        int a, b, w;
        bool operator< (const Edge &W) const {
            return w < W.w;
        }
    }edges[M];
    
    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) p[i] = i;
        
        int res = 0;
        int j = 0;
        for (int i = 0; i < m; ++i) {
            int op, a, b, w;
            cin >> op >> a >> b >> w;
            if (op == 1) {
                res += w;
                a = find(a);
                b = find(b);
                if (a != b) {
                    p[a] = b;
                }
            } else if (op == 2) {
                edges[j] = {a, b, w};
                j += 1;
            }
        }
        
        sort(edges, edges + j);
        for (int i = 0; i < j; ++i) {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a);
            b = find(b);
            if (a != b) {
                p[a] = b;
                res += w;
            }
        }
        
        cout << res << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    题目51144连接格点

    C++代码如下,

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 1e6 + 10, M = 2 * N;
    int n, m;
    int p[N];
    
    struct Edge {
        int a, b, w;
        bool operator< (const Edge &W) const {
            return w < W.w;
        }
    }edges[M];
    
    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n * m; ++i) p[i] = i;
        
        int x1, y1, x2, y2;
        while (cin >> x1 >> y1 >> x2 >> y2) {
            int w = 0;
            if (x1 == x2) w = 2;
            else w = 1;
            
            int a = (x1 - 1) * m + y1;
            int b = (x2 - 1) * m + y2;
            a = find(p[a]);
            b = find(p[b]);
            if (a != b) {
                p[a] = b;
            }
        }
        
        int k = 0;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j < m; ++j) {
                //(i,j) -> (i,j+1)
                int a = (i - 1) * m + j;
                int b = (i - 1) * m + j + 1;
                edges[k] = {a, b, 2};
                k += 1;
                
                //cout << "a = " << a << ", b = " << b << endl;
            }
        }
        
        //cout << "===" << endl;
        
        for (int j = 1; j <= m; ++j) {
            for (int i = 1; i < n; ++i) {
                
                //(i,j) -> (i+1,j)
                int a = (i - 1) * m + j;
                int b = i * m + j;
                edges[k] = {a, b, 1};
                k += 1;            
                
                //cout << "a = " << a << ", b = " << b << endl;
            }
        }
        
        sort(edges, edges + k);
        
        int res = 0;
        for (int i = 0; i < k; ++i) {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a);
            b = find(b);
            if (a != b) {
                p[a] = b;
                res += w;
            }
        }
        
        cout << res << endl;
           
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
  • 相关阅读:
    用神经网络实现一次加法运算
    一步一步搭建,功能最全的权限管理系统之动态路由菜单(一)
    今日睡眠质量记录79
    【cpolar】搭建我的世界Java版服务器,公网远程联机
    Javase ------> 泛型
    修饰生物素DIAZO-生物素-PEG3-DBCO|重氮-生物素-三聚乙二醇-二苯基环辛炔
    设计模式~迭代器模式(Iterator)-20
    如何使用群晖NAS中FTP服务开启与使用固定地址远程上传下载本地文件?
    Mybatis-Plus实现乐观锁
    【Harmony OS】【JAVA UI】鸿蒙应用如何集成OKHttp网络三方库
  • 原文地址:https://blog.csdn.net/YMWM_/article/details/137295303