zoukankan      html  css  js  c++  java
  • AcWing 346. 走廊泼水节

    题目思路
    将一个最小生成树的图,添加一些边,使得成为一个完全图,并且生成的完全图的最小生成树还是原树
    算法分析
    构建最小生成树的Kruskal算法

    1. 首先将所有的边按照从小到大的顺序排序
    2. 对于一条边(x,y,w),如果x和y在不在一个连通块中,就说明他们之间没有边相连那么我们相连之后,现在这两个点,各自所在的连通块(集合),都拥有了一个最短边,也就是(x,y,w)

    最小生成树已经确定了,那么原来两个连通块的其他点怎么办?
    假设(S_x)表示为(x)之前所在的连通块,那么(S_y)表示(y)之前所在的连通块。
    由于我们不能破坏最小生成树,所以我们原来这两个连通块必须具有如下性质:假设点A属于(S_x)这个集合,点B属于(S_y)这个集合,那么A与B之间的距离,必须大于之前的(w)否者就会破坏之前的最小生成树,所以说

    [A与B之间的距离最小为w+1 ]


    假如(S_x)(p)个元素,然后(S_y)(q)个元素,那么将(S_x)(S_y)连通块中所有的点相连,就会增加:

    [p × q - 1条边 ]

    每条边的最小长度为(w + 1)
    所以就会得出

    [(w + 1) × (p × q)为两个连通块成为完全图的最小代价 ]

    实现代码

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 6010;
    
    struct Edge
    {
        int a, b, w;
        bool operator < (const Edge & t)
        {
            return w < t.w;
        }
    }e[N];
    
    int n;
    int T;
    int p[N], s[N];
    
    int find(int x)
    {
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    int main()
    {
        cin >> T;
        while(T --)
        {
            cin >> n;
            for(int i = 0;i < n - 1;i++)
            {
                cin >> e[i].a >> e[i].b >> e[i].w;
            }
            
            sort(e, e + n - 1);
            
            for(int i = 1;i <= n;i++) p[i] = i, s[i] = 1;
            int res = 0;
            for(int i = 0;i < n - 1;i++)
            {
                int a = find(e[i].a), b = find(e[i].b), w = e[i].w;
                if(a != b)
                {
                    p[a] = b;
                    res += (s[b] * s[a] - 1) * (w + 1);
                    s[b] += s[a];
                }
            }
            cout << res << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    【20170923】2017暑假北京学习 day 3
    Leetcode 39
    事无巨细 | 访问一个网站的过程
    Leetcode 77
    排序 | 快速排序
    排序 | 堆排序
    Leetcode 60
    Leetcode 51
    海量数据处理的解法
    Leetcode 99
  • 原文地址:https://www.cnblogs.com/zykBlog/p/13849838.html
Copyright © 2011-2022 走看看