• 最小生成树kruskal


    编写一个程序,对于给定的加权图G=(v,E),输出其最小生成树的各边权值总和。

    输入:

           第一行v  e G的顶点数和边数。

          后面的,si   ti    wi    si  ti 表示连接的两个顶点的编号。wi 表示第i条边的权值

    输出:

      最小生成树的各边权值总和。占一行。

    限制:

       1<=|V|<=10000  0<=|E|<=100000   0<=wi<=10000    图G连通 不存在多边重复  不存在自身循环。

    输入示例:

    6  9

    0  1  1

    0  2  3

    1  2  1

    1  3  7

    2  4  1

    1  4  3

    3  4  1

    3  5  1

    4  5  6

    输出示例:

    5

    题解:

      克鲁斯卡尔算法:

    1:将图G(V,E)的边ei 按权值升序(降序)排列。

    2:设最小生成树的边的集合为K,并将其初始化为空。

    3:在保证K并上{ei}不出现环的前提下,按i=1,2,3,……,|E|的顺序将ei添加至K,直到|K|=|V|-1.

    算法复杂度:O(|E|log|E|)。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn=10000;
    const int INF=(1<<29);
    class DisjointSet
    {
    public:
        vector<int>rank,p;
        DisjointSet(){}
        DisjointSet(int size)
        {
            rank.resize(size,0);
            p.resize(size,0);
            for(int i=0;i<size;i++)
                makeSet(i);
        }
        void makeSet(int x)
        {
            p[x]=x;
            rank[x]=0;
        }
        bool same(int x,int y)
        {
            return findSet(x)==findSet(y);
        }
        void unite(int x,int y)
        {
            link(findSet(x),findSet(y));
        }
        void link(int x,int y)
        {
            if(rank[x]>rank[y])
            {
                p[y]=x;
            }
            else
            {
                p[x]=y;
                if(rank[x]==rank[y])
                {
                    rank[y]++;
                }
            }
        }
        int findSet(int x)
        {
            if(x!=p[x])
            {
                p[x]=findSet(p[x]);
            }
            return p[x];
        }
    };
    class Edge
    {
    public:
        int source,target,cost;
        Edge(int source=0,int target=0,int cost=0):source(source),target(target),cost(cost){}
        bool operator <(const Edge &e)const{return cost<e.cost;}
    };
    int kruskal (int N,vector<Edge>edges)
    {
        int totalCost=0;
        sort(edges.begin(),edges.end());
        DisjointSet dset=DisjointSet(N+1);
        for(int i=0;i<N;i++)
        {
            dset.makeSet(i);
        }
        int source,target;
        for(int i=0;i<edges.size();i++)
        {
            Edge e=edges[i];
            if(!dset.same(e.source,e.target))
            {
                totalCost+=e.cost;
                dset.unite(e.source,e.target);
            }
        }
        return totalCost;
    }
    int main()
    {
        int N,M,cost;
        int source,target;
        cin>>N>>M;
        vector<Edge> edges;
        for(int i=0;i<M;i++)
        {
            cin>>source>>target>>cost;
            edges.push_back(Edge(source,target,cost));
        }
        cout<<kruskal(N,edges)<<endl;
        return 0;
    }

    今天也是元气满满的一天!good luck!

  • 相关阅读:
    Docker ntpdate Permition error
    Sublime+Golang Plugin
    顺序表和链表的区别
    Python 性能优化——对象绑定
    Fix git 提交代码错误
    UVa 10523
    UVa 10551
    UVa 10814
    UVa 10925
    Practice Round China New Grad Test 2014 报告
  • 原文地址:https://www.cnblogs.com/cattree/p/7788337.html
Copyright © 2020-2023  润新知