核心思想
对所有的边按照权重从小到大排序,然后按顺序选取边构造[[最小生成树]]。选择的边必须满足:加入这条边不会在已选取的边中形成环路 (对于是否形成环,用并查集判断)。
输入:一张连通的无向图
HDU 1301 Jungle Roads(最小生成树问题)
#include <bits/stdc++.h>
using namespace std;
#define mod (100001)
#define ll long long
#define x first
#define y second
typedef pair<char, pair<char, int>> P;
vector<P> edges;
int pa[mod] {};
void init_dsu() {
for (int i = 0; i < mod; i++) {
pa[i] = i;
}
}
int find(int x) {
return pa[x] == x ? x : (pa[x] = find(pa[x]));
}
void unit(int x, int y) {
pa[find(x)] = find(y);
}
bool cmp(P& a, P& b) {
return a.y.y < b.y.y;
}
int kruskal() {
int sum = 0;
int p1, p2;
for (auto &it : edges) {
p1 = find(it.x);
p2 = find(it.y.x);
if (p1 != p2) {
unit(p1, p2);
sum += it.y.y;
}
}
return sum;
}
bool work = true;
void solve() {
int n;
cin >> n;
if (!n) {
work = false;
return;
}
edges.clear();
init_dsu();
char v; int es;
char m; int w;
for (int j = 0; j < n-1; j++) {
cin >> v >> es;
for (int i = 0; i < es; i++) {
cin >> m >> w;
edges.push_back({v, {m, w}});
}
}
sort(edges.begin(), edges.end(), cmp);
cout << kruskal() << endl;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
while (work)
solve();
return 0;
}