最优规划
有很多城市之间已经建立了路径,但是有些城市之间没有路径联通。为了联通所有的城市,现在需要添加一些路径,为了节约,需要满足添加总路径是最短的。
输入
第一行 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
裸的kruskal,将需要添加的边排序加进去,当总的边数等于n-1时符合条件
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int x, y, d, n, m, s;
int pre[100005];
int cnt;
struct node{
int u, v, w;
}k[100005];
bool cmp(node x, node y){
return x.w < y.w;
}
int find(int x){
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y){
pre[find(x)] = find(y);
}
void kruskal(){
long long sum = 0;//会爆int
sort(k + 1, k + 1 + s,cmp);
for (int i = 1; i <= s; i++){
if (find(k[i].u) != find(k[i].v)){
sum += k[i].w;
cnt++;//记录边数
join(k[i].u, k[i].v);
}
if (cnt == n - 1){
cout << sum << endl;
return;
}
}
cout << "Concubines can't do it." << endl;//不符合条件
return;
}
int main(){
cin >> n >> m >> s;
cnt = 0;
for (int i = 1; i <= n; i++)
pre[i] = i;
for (int i = 1; i <= m; i++){
cin >> x >> y >> d;
if (find(x) != find(y)){
join(x, y);
cnt++;//已有的数量
}
}
for (int i = 1; i <= s; i++){
cin >> k[i].u >> k[i].v >> k[i].w;
}
kruskal();
return 0;
}