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

 要注意计算总长度的数据范围类型为long long

思路  :先将已经存在的路径都都并在一起,然后将剩下规划的路线按照最小生成树的方法处理。

最后再计算产生树的个数如果只有一个说明可以把所有的城市连在一起,如果大于1说明不能连在一起

#include<bits/stdc++.h>
#include<algorithm>

using namespace std;
typedef long long ll;

struct node
{
	int x,y;
	ll len;
}road[1000005];

bool cmp(node a,node b)
{
	return a.len < b.len;
}

int a[1000005];

int find(int x)
{
	if (a[x]==x)
		return x;
	else return a[x] = find(a[x]);
}

bool unite(int x,int y)
{
	x = find(x);
	y = find(y);
	if (x!=y)
	{
		if (x<y)
			a[y] = x;
		else
			a[x] = y;
		return 1;
	}
	else
		return 0;
}

int main()
{
	int n,m,s;
	scanf("%d %d %d",&n,&m,&s);
	for (int i=1;i<=n;i++)
		a[i] = i;
	for (int i=0;i<m+s;i++)
		scanf("%d %d %lld",&road[i].x,&road[i].y,&road[i].len);
	sort(road+m,road+m+s,cmp);
	ll sum = 0;
	for (int i=0;i<m+s;i++)
	{
		if (i<m)
			unite(road[i].x,road[i].y);
		else
		{
			int x = road[i].x;
			int y = road[i].y;
			if (find(x)!=find(y)) 
			{
				unite(road[i].x,road[i].y);
				sum += road[i].len;
			}
//			if (unite(road[i].x,road[i].y))
//				sum += road[i].len;
		}
	}		
	int cnt = 0;
	for (int i=1;i<=n;i++)
	{
		if (i==find(i))
			cnt++;
	}	
	if (cnt==1)	
		printf("%lld\n",sum);
	else
	{
		printf("Concubines can't do it.\n");
	}
	return 0;
}
 

猜你喜欢

转载自blog.csdn.net/qq_40912854/article/details/88959888
今日推荐