https://www.luogu.com.cn/problem/P5631
类似SUM那题
挖掉某一块后看是否还是能构成生成树
考虑分治,用按秩合并并查集来维护联通性
code:
#include<bits/stdc++.h>
#define N 2000050
using namespace std;
struct E {
int u, v, c;
} e[N];
int cmp(E x, E y) {
return x.c < y.c;
}
int fa[N], siz[N], n, m;
int get(int x) {
return fa[x] == x ? x : get(fa[x]);
}
int merge(int x, int y) {
x = get(x), y = get(y);
if(x == y) return 0;
if(siz[x] > siz[y]) swap(x, y);
fa[x] = y, siz[y] += siz[x];
return x;
}
void del(int x) {
siz[fa[x]] -= siz[x];
fa[x] = x;
}
void cdq(int l, int r, int L, int R) {
if(l == r) {
//if(l == e[m].c + 1) printf("%d ", siz[get(1)]);
if(siz[get(1)] == n) {
printf("%d", l);
exit(0);
}
return ;
}
vector<int> sta;
int mid = (l + r) >> 1, pos = R;
while(pos >= L && e[pos].c > mid) sta.push_back(merge(e[pos].u, e[pos].v)), pos --;
cdq(l, mid, L, pos);
while(sta.size()) del(sta.back()), sta.pop_back(); sta.clear();
for(int i = L; i <= pos; i ++) sta.push_back(merge(e[i].u, e[i].v));
cdq(mid + 1, r, pos + 1, R);
while(sta.size()) del(sta.back()), sta.pop_back(); sta.clear();
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++) scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].c);
for(int i = 1; i <= n; i ++) fa[i] = i, siz[i] = 1;
sort(e + 1, e + 1 + m, cmp);
cdq(0, e[m].c + 1, 1, m);
return 0;
}