• hdu 3371(kruskal)


    Connect the Cities

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 15569    Accepted Submission(s): 4108


    Problem Description
    In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities again, but they don’t want to take too much money.  
     
    Input
    The first line contains the number of test cases.
    Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected cities.
    To make it easy, the cities are signed from 1 to n.
    Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.
    Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.
     
    Output
    For each case, output the least money you need to take, if it’s impossible, just output -1.
     
    Sample Input
    1 6 4 3 1 4 2 2 6 1 2 3 5 3 4 33 2 1 2 2 1 3 3 4 5 6
     
    Sample Output
    1
     
     
    题意:多组测试用例,每组第一行是n m k,表示n个城市,m条路的信息,和已经连接上的K个城市信息。
    接下来m行每行是城市A到B建路需要的花费。再接下来k行每行第一个数为t,之后t个数表示已经连接在一起的城市。
    在已经连接的基础上进行城市间的连通,求解全部联通的最少费用。不能连通输出-1
     
    典型的kruskal算法,并查集和贪心算法求解最小生成树,最后判断城市生成的树是否唯一。
     
    这题非常奇怪,用JAVA死活TLE,然后又用c++写,然后还是超时,然后又把启发式搜索什么的加进去也没用,最后改成g++就过了..过了。。
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    int father[505];
    int dep[505];
    struct Seg
    {
        int x,y,len;
    } seg[25010];
    int cmp(Seg a,Seg b)
    {
        return a.len <b.len;
    }
    int _find(int x)
    {
        if(x==father[x])return x;
        return _find(father[x]);
    }
    int main()
    {
        int tcase ;
        scanf("%d",&tcase);
        while(tcase--)
        {
            int n,m,t;
            scanf("%d%d%d",&n,&m,&t);
            for(int i=1; i<=n; i++)
            {
                father[i]=i;
                dep[i]=0;
            }
            for(int i=0; i<m; i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                seg[i].x=x;
                seg[i].y=y;
                seg[i].len=z;
            }
            for(int i=0; i<t; i++)
            {
                int num,x;
                scanf("%d%d",&num,&x);
                num--;
                while(num--)
                {
                    int y;
                    scanf("%d",&y);
                    x = _find(x);
                    y = _find(y);
                    if(x!=y)
                    {
                        if(dep[x]==dep[y])
                        {
                            father[x] = y;
                            dep[y]++;
                        }
                        else if(dep[x]<dep[y])
                        {
                            father[x] = y;
                        }
                        else
                        {
                            father[y]=x;
                        }
    
                    }
                }
            }
            sort(seg,seg+m,cmp);
            int sum=0;
            for(int i=0; i<m; i++)
            {
                int x = _find(seg[i].x);
                int y = _find(seg[i].y);
                if(x!=y)
                {
                    if(dep[x]==dep[y])
                    {
                        father[x] = y;
                        dep[y]++;
                    }
                    else if(dep[x]<dep[y])
                    {
                        father[x] = y;
                    }
                    else
                    {
                        father[y]=x;
                    }
                    sum+=seg[i].len;
                }
            }
            int ans=0;
            for(int i=1; i<=n; i++)
            {
                if(father[i]==i) ans++;
            }
            if(ans==1) printf("%d
    ",sum);
            else printf("-1
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    循环链表问题
    非常有用的编程学习网站
    我的单例模式(C++)
    C# xml解析
    设计模式趣解
    简单工厂(C++)
    贝塞尔曲线 原理
    C++ 1.#QNAN0;1.#QNAN0
    [NOI2018]屠龙勇士 excrt
    [NOI.AC#30]candy 贪心
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5325678.html
Copyright © 2020-2023  润新知