hpuoj 最优规划(最小生成树)

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

输入

第一行 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

很显然是最小生成树,前m条道路先加入,后面的s条取短的,比赛的时候忘了kruskal咋写也是难受。

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n, m, b;
ll pre[100010];
ll cnt = 0;
struct node{
	ll b, e, v;
	bool operator < (const node a)const
	{
		return this->v < a.v;
	}
}a[100010];
inline ll find(ll x)
{
	return pre[x] == x ? x : pre[x] = find(pre[x]);
}
inline void join(ll x, ll y)
{
	pre[find(y)] = find(x);
}

void kruskal(){
	ll num = 0;
	sort(a + 1, a + 1 + m);  //对后面的m条边排序
	for (int i = 1; i <= m; i++)
	{
		if (find(a[i].b) == find(a[i].e))  
			continue;
		cnt += a[i].v;
		join(a[i].b, a[i].e);
	}
	for (int i = 1; i <= n; i++)
		if (find(i) == i)
			num++;
	if (num == 1)    //若能联通
		cout << cnt << endl;
	else
		cout << "Concubines can't do it." << endl;
}
int main(){
	cin >> n >> b >> m;
	ll x, y, z;
	for (int i = 1; i <= n; i++)
		pre[i] = i;
	for (int i = 1; i <= b; i++)
		cin >> x >> y >> z, join(x, y);
	for (int i = 1; i <= m; i++)
		cin >> a[i].b >> a[i].e >> a[i].v;
	kruskal();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值