7_22_T题 Constructing Roads
题意
现在有一些顶点,顶点之间连线的花费给出,有些顶点之间已经连了线,求把所有点连通的最小花费。
思路
最小生成树,先把已经连通的点连起来,再跑最小生成树就行了。
代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxm = 1e6 + 10;
const int maxn = 1e5 + 10;
typedef long long ll;
struct Edges{
int u,v,w;
Edges(){};
Edges(int u,int v,int w):u(u),v(v),w(w){};
bool operator < (const Edges & b) const {
return w < b.w;
}
}edge[maxm];
int fa[maxn];
int Find(int x){
return fa[x] == x ? x :fa[x] = Find(fa[x]);
}
bool Union(int x ,int y){
x = Find(x);
y = Find(y);
if(x == y) return false;
fa[x] = y;
return true;
}
ll lent = 0;
void init(int n){
for(int i = 0 ; i <= n ; i ++)
fa[i] = i;
lent = 0;
}
int main (){
int T;
while (~scanf("%d", &T)){
init(T);
int cnt = 0;
for(int i = 0 ; i < T ; i ++){
for(int k = 0; k < T ; k ++){
int len;
scanf("%d", &len);
edge[cnt++] = Edges(i+1,k+1,len);
}
}
int q;
scanf("%d", &q);
for(int i = 0 ; i < q ; i ++){
int u,v;
scanf("%d %d", &u,&v);
Union(u,v);
}
sort(edge,edge+cnt);
for(int i = 0 ; i < cnt ; i ++){
Edges & e = edge[i];
if(Union(e.u,e.v)) {
lent += e.w;
}
}
printf("%lld\n", lent);
}
}