zoukankan      html  css  js  c++  java
  • 并查集(KRUSKAL算法)

    先上一道例题:

    【例4-9】城市公交网建设问题

    时间限制: 1000 ms 内存限制: 65536 KB

    【题目描述】

    有一张城市地图,图中的顶点为城市,无向边代表两个城市间的连通关系,边上的权为在这两个城市之间修建高速公路的造价,研究后发现,这个地图有一个特点,即任一对城市都是连通的。现在的问题是,要修建若干高速公路把所有城市联系起来,问如何设计可使得工程的总造价最少?

    【输入】

    n(城市数,1<=n<=100)

    e(边数)

    以下e行,每行3个数i,j,wij,表示在城市i,j之间修建高速公路的造价。

    【输出】

    n-1行,每行为两个城市的序号,表明这两个城市间建一条高速公路。

    【输入样例】

    5 8
    1 2 2
    2 5 9
    5 4 7
    4 1 10
    1 3 12
    4 3 6
    5 3 3
    2 3 8
    【输出样例】

    1 2
    2 3
    3 4
    3 5

    献上标程:
        #include<cstdio>
        #include<cstring>
        #include<vector>
        #include<algorithm>
        using namespace std;
        struct sd{
            int a,b,c;
        }mp[1000],num[1000];
        int n,m,x[1000],ans=0,numm=0;
        bool cmp1(sd aa,sd bb)
        {
            if(aa.a<bb.a) return true;
            if(aa.a==bb.a&&aa.b<bb.b) return true;
            return false;
        }
        bool cmp(sd aa,sd bb)
        {
            if(aa.c<bb.c) return true;
            return false;
        }
        int father(int v)
        {//☣
            int i,j=v;
            while(v!=x[v])
            v=x[v];
            return v;
        }
        int main()
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;++i)
              x[i]=i;
            for(int i=1;i<=m;++i)
            {
                scanf("%d%d%d",&mp[i].a,&mp[i].b,&mp[i].c);
            }
            sort(mp+1,mp+1+m,cmp);
            for(int i=1;i<=m;++i)
            {
                int a1=father(mp[i].a),b1=father(mp[i].b);
                if(a1!=b1)
                {
                    numm++;
                    num[numm]=mp[i];
                    ans+=mp[i].c;
                    x[a1]=b1;
                }
            }
            for(int i=1;i<=numm;++i)
            {
                if(num[i].a>num[i].b)
                swap(num[i].a,num[i].b);
            }
            sort(num+1,num+1+numm,cmp1);
            for(int i=1;i<=numm;++i)
            {
                printf("%d %d
    ",num[i].a,num[i].b);
            }
            //printf("%d",ans);
        }
    

    /*
    5 8
    1 2 2
    2 5 9
    5 4 7
    4 1 10
    1 3 12
    4 3 6
    5 3 3
    2 3 8
    */
    函数中father的作用就是找出当前点是否连在了一起(找出他们的终极老父亲),如果他们终极老父亲不同,就把它们并在一起形成一个新的集合,拥有一个共同的(终极老父亲)。

    认真理解!!!

  • 相关阅读:
    458 The Decoder
    488 Triangle Wave
    10300 Ecological Premium
    10071 Back to High School Physics
    when I update Ubuntu, there are somthing wrong with my gnuradio
    gnuradio 3.3.0rc0 和gnuradio 3.3.0里边的文件又改名字了。。
    source insight 使用技巧
    重装gnuradio遇到一点问题
    Ubuntu 11.04 method of logout and login
    python 中用SWIG包装C和C++和接口生成的例子
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13331087.html
Copyright © 2011-2022 走看看