HDU problem G-最短路

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.<br>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.<br>To make it easy, the cities are signed from 1 to n.<br>Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.<br>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.<br>
 

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

题意:

发洪水了,把一部分道路给冲坏了,但还是有一部分好的,给你一部分能够修的道路,和修这些道路的费用,还有一部分道路没坏的城市群。

问:能不能将所有城市来连接起来,能的话,输出所需费用,否则输出 -1

输入:

第一行,n,m,k,表示城市数目,可以维修的道路数,道路没坏的城市群

接下来m行,每行x,y,v;表示,连接x,y的城市间道路维修需要v的费用

接下来k行,每行第一个数t,表示这个城市群有t个城市,接下来的t个数表示道路没坏的城市

输出

费用或者-1

扫描二维码关注公众号,回复: 1025481 查看本文章

思路

kruskal算法,特殊判断是否全部连接,和提前将不修路的城市连起来。

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int x;
    int y;
    int value;
    bool operator <(const node & t)//重载<号
    {
        return value<t.value;
    }
}a[25005];
int fa[505];
int Find(int x)
{
    if(fa[x]!=x)
        fa[x]=Find(fa[x]);
    return fa[x];
}
int main()
{
    int num;
    scanf("%d",&num);
    while(num--)
    {
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<=n;++i)
            fa[i]=i;
        int x,y,v;
        for(int i=0;i<m;++i)
        {
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].value);
        }
        int K=0;
        for(int i=0;i<k;++i)
        {
            int N;
            scanf("%d%d",&N,&x);
            int p=Find(x);
            while(--N)//因为有一个已经输入了
            {
                scanf("%d",&y);
                int q=Find(y);
                if(p!=q)
                {
                    fa[q]=p;//连接城市
                    ++K;//已连接道路加一
                }
            }

        }
        sort(a,a+m);
        int ans=0;
        bool temp=false;
        for(int i=0;i<m;++i)//kruskal算法
        {
            int p=Find(a[i].x);
            int q=Find(a[i].y);
            if(p!=q)
            {
                fa[q]=p;
                ans+=a[i].value;
                ++K;
            }
            if(K==n-1)
            {
                temp=true;
                break;
            }
        }
        if(temp)//判断输出
            printf("%d\n",ans);
        else
            printf("-1\n");
    }
    return 0;
}

//完美的代码

猜你喜欢

转载自blog.csdn.net/sdau_fangshifeng/article/details/80370567