按照边的权值从小到大排序,依次加入,并删除能够删除的权值最小的一条边,用 set 维护当前所有边的边权,并查集维护联通性,LCT 维护两点间最小值和 link cut 操作即可
#include#define mp make_pairusing namespace std;typedef unsigned long long ull;typedef long long ll;template inline void read(_T &f) { f = 0; _T fu = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();} while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();} f *= fu;}const int N = 250000 + 10;struct ele { int u, v, a; bool operator < (const ele A) const {return a < A.a;}}p[N];set < pair > Min;int fa[N], ch[N][2], rev[N], minn[N], val[N], wz[N], st[N], f[N], n, m, len, cnt, ans = INT_MAX;int isroot(int u) {return ch[fa[u]][0] != u && ch[fa[u]][1] != u;}int get(int u) {return ch[fa[u]][1] == u;}void update(int u) { minn[u] = val[u]; wz[u] = u; if(minn[ch[u][0]] < minn[u] && ch[u][0]) minn[u] = minn[ch[u][0]], wz[u] = wz[ch[u][0]]; if(minn[ch[u][1]] < minn[u] && ch[u][1]) minn[u] = minn[ch[u][1]], wz[u] = wz[ch[u][1]];}void pushdown(int u) { if(rev[u]) { swap(ch[u][0], ch[u][1]); rev[ch[u][0]] ^= 1; rev[ch[u][1]] ^= 1; rev[u] ^= 1; }}void rotate(int u) { int old = fa[u], oldd = fa[old], k = get(u); if(!isroot(old)) ch[oldd][get(old)] = u; fa[u] = oldd; ch[old][k] = ch[u][k ^ 1]; fa[ch[u][k ^ 1]] = old; fa[old] = u; ch[u][k ^ 1] = old; update(old); update(u);}void splay(int u) { st[len = 1] = u; for(int i = u; !isroot(i); i = fa[i]) st[++len] = fa[i]; for(int i = len; i >= 1; i--) pushdown(st[i]); for(; !isroot(u); rotate(u)) if(!isroot(fa[u])) rotate(get(u) == get(fa[u]) ? fa[u] : u);}void access(int u) { for(int i = 0; u; i = u, u = fa[u]) { splay(u); ch[u][1] = i; update(u); }}void makeroot(int u) { access(u); splay(u); rev[u] ^= 1;}void link(int u, int v) { makeroot(u); fa[u] = v;}void cut(int u, int v) { makeroot(u); access(v); splay(v); fa[u] = ch[v][0] = 0; update(v);}int query(int u, int v) { makeroot(u); access(v); splay(v); return wz[v];}int find(int x) {return f[x] == x ? x : f[x] = find(f[x]);}int main() { read(n); read(m); for(int i = 1; i <= n; i++) f[i] = i, val[i] = INT_MAX; for(int i = 1; i <= m; i++) { read(p[i].u); read(p[i].v); read(p[i].a); } sort(p + 1, p + m + 1); for(int i = 1; i <= m; i++) { int x = p[i].u, y = p[i].v; if(find(x) != find(y)) { cnt++; f[find(x)] = find(y); val[i + n] = p[i].a; link(i + n, x); link(i + n, y); Min.insert(mp(p[i].a, i)); } else { if(x == y) continue; int wz = query(x, y); val[i + n] = p[i].a; cut(wz, p[wz - n].u); cut(wz, p[wz - n].v); link(i + n, x); link(i + n, y); Min.erase(mp(p[wz - n].a, wz - n)); Min.insert(mp(p[i].a, i)); } if(cnt == n - 1) { set < pair > :: iterator it = Min.begin(); ans = min(ans, p[i].a - it -> first); } } cout << ans << endl; return 0;}