HDU - 3371 Connect the Cities (克鲁斯卡尔)

最近zx很烦恼,因为呀,zx看上了一台平板电脑,可是zx并没有那么多的钱。

“那可怎么办呢?”zx心想,“只能重操旧业了啊!”,于是zx又决定开始接单赚钱了。

但是问题来了,zx要熟悉地形呀,他可不想贸然前进,毕竟pls可不是那么好惹的。

现在zx的地图上有若干个地点,zx很清楚有的地点与其他地点联系在一起,但是有的地点zx却没那么了解了。

为了方便接单,他需要使得他地图上的所有点联系在一起,但是如果连起来之后任意点之间走的路太长,zx遇到pls的风险就会增加。

他可不想在接单的时候遇到pls,所以他需要聪明的你的帮助!

Input

数据量较大,建议使用scanf输入。

第一行包含测试用例的数量。

每个测试用例以三个整数n,m,k开始(3 <= n <= 500, 0 <= m <= 25000, 0 <= k <= 100)——n代表地点数量(从1 - n编号),m代表边数。

之后m行 每行三个整数u, v, w (0 <= w <= 1000)——代表编号 u 与 v 的地点之间有一条权值为w的边(数据有重边)。

之后k行 每行第一个整数 t (2 <= t <= n) ——代表zx已经知道 t 个地点之间联系在了一起,往后 t 个整数代表地点的编号。 

Output

对于每个样例,zx想要使地图上所有的点联系在一起同时保证遇到pls的风险最小,输出还需要连接的边长总和。

如果不可能将所有点联系在一起,则输出-1。

Sample Input

2

7 7 2
1 3 2
2 3 1
3 5 5
4 3 3
7 4 6
4 6 3
2 7 4
3 4 5 6
2 2 3

4 3 1
1 2 3
2 3 1
1 3 2
3 1 2 3

Sample Output

9
-1

很明显的最小生成树,因为不想敲prime了 ,写了一发克鲁斯卡尔,就过了。其中也有一些技巧吧。就是在最后判断到不了的情况,如果是一个集合的话,就是会到达的,不是一个集合的话,是不会到达的,最后再判断了一下集合的数量,再输出结果。      

#include<iostream>
using namespace std;
#include<bits/stdc++.h>
const int maxn=25005;
typedef long long ll;
typedef pair<int,int> p;
const int inf=1000000;

int n,m,k;
int pre[maxn];

typedef struct 
{
	int a,b,val;
}point;

point dian[maxn];

bool cmp(point a,point b)
{
	return a.val<b.val;
}

int find(int x)
{
	return x==pre[x]?x:pre[x]=find(pre[x]);
}

void join(int x,int y)
{
	int a=find(x);
	int b=find(y);
	if(a!=b)
	{
		pre[a]=b;
	}
	
}

void init()
{
	for(int i=1;i<=n;i++)
		pre[i]=i;
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
			scanf("%d%d%d",&n,&m,&k);
			init();
			for(int i=0;i<m;i++)
			{
				scanf("%d%d%d",&dian[i].a,&dian[i].b,&dian[i].val);
			}
		
		while(k--)
		{
			int num,a1,a2;
			scanf("%d%d",&num,&a1);
			for(int i=1;i<num;i++)
			{
				scanf("%d",&a2);
				join(a1,a2);
			}
		}
		sort(dian,dian+m,cmp);
		
		int ans=0;
		for(int i=0;i<m;i++)
		{
			int fx=find(dian[i].a);
			int fy=find(dian[i].b);
			if(fx!=fy)
			{
				pre[fx]=fy;
				ans+=dian[i].val;
			}
		}
	int k=0;
	for(int i=1;i<=n;i++)
	{
		if(pre[i]==i)
			k++;
	}	
	if(k==1)	
		printf("%d\n",ans);
	else
		printf("-1\n");
	}
	
	return 0;
} 
发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/89300652