克鲁斯卡尔算法
最小生成树——(性质)其最大边权为生成树中最大边权最小的
所以直接使用最小生成树即可
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int par[1001], v[1001], ans[1001];
struct node {
int from, to, cost;
} nds[15001];
bool cmp(node n1, node n2) {
return n1.cost < n2.cost;
}
int fd(int id) {
return (par[id] != id) ? par[id] = fd(par[id]) : par[id];
}
void inti(int n) {
for (int i = 1; i <= n; i++) {
par[i] = i;
v[i] = 1;
}
}
int main() {
int n, m, i, j, a, b, cnt;
while (scanf("%d%d", &n, &m) != EOF) {
for (i = 0; i < m; i++) {
scanf("%d%d%d", &nds[i].from, &nds[i].to, &nds[i].cost);
}
sort(nds, nds + m, cmp);
inti(n);
cnt = 0;
for (j = 0; j < m; j++) {
a = fd(nds[j].from);
b = fd(nds[j].to);
if (a != b) {
if (v[a] < v[b]) {
v[b] += v[a];
par[a] = b;
} else {
v[a] += v[b];
par[b] = a;
}
cnt++;
ans[cnt] = j;
if (cnt == n - 1)break;
}
}
printf("%d\n", nds[ans[n - 1]].cost);
printf("%d\n", n - 1);
for (i = 1; i <= n - 1; i++) {
printf("%d %d\n", nds[ans[i]].from, nds[ans[i]].to);
}
}
}