最优规划(HPU校赛并查集)

L. 最优规划

单测试点时限: 1.0 秒

内存限制: 512 MB

有很多城市之间已经建立了路径,但是有些城市之间没有路径联通。为了联通所有的城市,现在需要添加一些路径,为了节约,需要满足添加总路径是最短的。

输入

第一行 3 个整数 n, m, s, 分别表示城市的数量、已经存在的路的数量、可修的路的数量。
之后的 m 行,每行 3 个整数 x, y, d,表示点 x 到点 y 有一条长度为 d 的已经存在的路径。
之后的 s 行,每行 3 个整数 x, y, d,表示点 x 到点 y 有一条长度为 d 的可修的路径。
0<n,m,s,d≤105 。

输出

输出一个整数表示需要添加的最短的路径长度。
若果无论如何也无法使得所有的城市联通,输出 Concubines can't do it. 。

样例

input

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

output

5
 #include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
using namespace std;
int father[100010];
struct node{
	int x,y;
	int val;
}qwe[100010];
bool cmp(node c,node d)
{
	return c.val<d.val;
}
int find(int c)
{
	int w=c;
	while(w!=father[w])
	{
		w=father[w];
	}
	return w;
}
int join(int c,int d)
{
	int x1=find(c);
	int x2=find(d);
	if(x1!=x2)
	{
		if(x2>x1)  father[x2]=x1;//优化,比赛时没想到,直接超时了。。。。 
		else father[x1]=x2;
	  return 1;
	}
	return 0;
}
int main()
{
	
	int n,m,s;
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=n;i++) father[i]=i;
	for(int i=0;i<m;i++)
	{
		int a,b,val;
		scanf("%d%d%d",&a,&b,&val); 
		join(a,b);
		
	}
//	memset(vis,0,sizeof(vis));
	for(int i=0;i<s;i++)
	{
		scanf("%d%d%d",&qwe[i].x,&qwe[i].y,&qwe[i].val);
	}
	sort(qwe,qwe+s,cmp);
	long long sum=0;
	for(int i=0;i<s;i++)
	{

	   if(join(qwe[i].x,qwe[i].y))
	   {
			sum+=qwe[i].val;
		}
		
	}
	int t=0;
	for(int i=1;i<=n;i++)
	{
		if(father[i]!=i) t++;
	}
	if(t==n-1)
	{
		printf("%lld\n",sum);
	}
	else printf("Concubines can't do it.\n");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值