在n个村庄之间修路使所有村庄连通 其中有些路已经修好了 求至少还需要修多长路
还是裸的最小生成树 我使用了克鲁斯卡尔算法,当拿出来一个边的两个端点已经是一个集合中就continue,
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<string>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define ll int
#define MAX 105
#define inf 0x3FFFFFFF
ll d[MAX][MAX], kind[MAX];
struct edge {
ll from, to, cost;
edge(ll a = 0, ll b = 0, ll c = 0) { from = a, to = b, cost = c; }
};
vector<edge> e;
bool cmp(edge e1, edge e2) {
return e1.cost < e2.cost;
}
ll find(ll k) {
if (k == kind[k]) return k;
else return kind[k] = find(kind[k]);
}
void unite(ll a, ll b) {
kind[find(b)] = kind[find(a)];
}
int main() {
ll N, Q, a, b; scanf("%d", &N);
for (int i = 1; i <= N; i++)kind[i] = i;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
scanf("%d", &d[i][j]);
if (j > i)e.push_back(edge(i, j, d[i][j]));
}
}
scanf("%d", &Q);
for (int i = 0; i < Q; i++) {
scanf("%d%d", &a, &b);
unite(a, b);
}
sort(e.begin(), e.end(), cmp);
ll res = 0;
for (int i = 0; i < e.size(); i++) {
edge t = e[i];
if (find(t.from) == find(t.to))continue;
res += t.cost; unite(t.from, t.to);
}
printf("%d", res);
}