杭电1863——Kruskal(克鲁斯卡尔)+并差集—最小生成树
# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>
# include <cstdlib>
using namespace std;
const int maxn = 200;
int r[maxn], f[maxn];
int m, n;
struct edg {
int from, to, val;
}e[maxn];
bool cmd(edg a, edg b) {
return a.val < b.val;
}
void init() {
for (int i = 0; i < m; i++) {
f[i] = i;
}
memset(r, 0, sizeof(r));
}
int fin(int x) {
return f[x] = f[x] == x ? x : fin(f[x]);
}
void meg(int x, int y) {
int a = fin(x);
int b = fin(y);
if (r[a] < r[b]) {
f[a] = b;
}
else {
f[b] = a;
if (r[a] == r[b]) {
r[a]++;
}
}
}
bool same(int x, int y) {
return fin(x) == fin(y);
}
int main() {
while (cin >> n >> m && n) {
init();
for (int i = 0; i < n; i++) {
cin >> e[i].from >> e[i].to >> e[i].val;
e[i].from--;
e[i].to--;
}
sort(e, e + n, cmd);
int sum = 0;
for (int i = 0; i < n; i++) {
if (same(e[i].from, e[i].to)) {
continue;
}
else {
sum += e[i].val;
meg(e[i].from, e[i].to);
}
}
int flag = 1;
for (int i = 0; i < m; i++) {
for (int j = i + 1; j < m; j++) {
if (!same(i, j)) {
flag = 0;
break;
}
}
}
if (flag) {
cout << sum << endl;
}
else {
cout << "?" << endl;
}
}
return 0;
}
目前已过