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;
    }
    
  • 相关阅读:
    POJ-1318(list.sort()输出不为字典序,map才是按字典序排列)
    C++ 进阶
    命令模式在MVC框架中的应用
    使用NoSQL Manager for MongoDBclient连接mongodb
    第一部分 学习函数式思维
    【剑指offer】复杂链表的复制
    Hadoop-2.4.0分布式安装手冊
    Impala中多列转为一行
    js(jquery)绑定点击事件
    hdu1243 最长公共子序列(LCS)
  • 原文地址:https://www.cnblogs.com/hezongdnf/p/13384584.html
Copyright © 2011-2022 走看看