有很多城市之间已经建立了路径,但是有些城市之间没有路径联通。为了联通所有的城市,现在需要添加一些路径,为了节约,需要满足添加总路径是最短的。
输入
第一行 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;
}