zoukankan      html  css  js  c++  java
  • 最小生成树

    prim

    先将一个点加入集合中,维护一个dis数组,表示该点距集合中的点的最小距离,每次选取dis的最小值,并把那个点加入集合,更新dis。

    可以用优先队列优化

    kruskal

    把所有的边按边权从小到大排序,利用并查集维护集合关系,对于每条边,若两点不在同一集合,则把两点连接。

    Boruvka

    假设每个点都是一个联通块,然后求出与当前联通块最近的一个联通块的距离,然后让两个块联通。

    每次联通块的个数都会少一半,所以会执行logn次

    #include <bits/stdc++.h>
    using namespace std;
    #define mem(a,b) memset(a,b,sizeof(a))
    #define pii pair<int,int>
    const int inf = 0x3f3f3f3f;
    const int maxn = 201110;
    const int M = 1e9+7;
    int n,m,k,ok;
    
    vector<pii> v[maxn];
    int pre[maxn];
    
    int find(int x)
    {
        return x==pre[x]?x:pre[x]=find(pre[x]);
    }
    
    int link[maxn],val[maxn];
    
    void Boruvka()
    {
        for(int i = 1; i <= n; i++) 
        {
            pre[i] = i;
        }
        int ans = 0;
        bool flag;
        do
        {
            flag = 0;
            mem(link,0);mem(val,inf);
            for(int i = 1; i <= n; i++)        
            {
                int x = find(i);
                for(auto j : v[i])
                {
                    int y = find(j.first);
                    if(x == y || j.second >= val[x]) continue;       //如果当前联通快和其他联通快之间有更短的边
                    link[x] = y;val[x] = j.second;
                }
            }
            for(int i = 1; i <= n; i++) 
            {
                int x = find(i);
                if(link[x] && x != find(link[x]))
                {
                    pre[x] = find(link[x]);
                    ans += val[x];
                    flag = 1;
                }
            }
        } while (flag);
        int x = find(1);
        for(int i = 1; i <= n; i++) 
        {
            if(find(i) != x)
            {
                cout<<"orz
    ";
                return;
            }
        }
        cout<<ans<<endl;
    }
    
    signed main()
    {
        cin>>n>>m;
        for(int i = 1,x,y,z; i <= m; i++) 
        {
            cin>>x>>y>>z;
            v[x].push_back({y,z});
            v[y].push_back({x,z});
        }
        Boruvka();
        return 0;
    }
    
  • 相关阅读:
    CF1439E
    CF1446
    CSP2020 游记
    CF1442
    CF1444E
    CF1444
    CF850F Rainbow Balls
    A
    uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数)
    loj536「LibreOJ Round #6」花札(二分图博弈)
  • 原文地址:https://www.cnblogs.com/hezongdnf/p/13384584.html
Copyright © 2011-2022 走看看