学克鲁斯卡尔重构树打的板子ovo 要学克鲁斯卡尔重构树见上一篇转的博客很详细
~~直接贴代码啦
#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define FOR(i, a, b) for(register int i = a; i >= b; -- i)
using namespace std;
const int maxn = 2e5 + 10;
int to[maxn << 1], head[maxn], nxt[maxn << 1], e;
int n, m, q, val[maxn], fa[maxn];
int f[maxn][20], dep[maxn];
struct egde
{
int x, y, z;
}E[maxn];
bool cmp(egde A, egde B)
{
return A.z > B.z;
}
void add(int x, int y)
{
to[++ e] = y;
nxt[e] = head[x];
head[x] = e;
}
int find(int x)
{
return fa[x] = x == fa[x] ? x : find(fa[x]);
}
void dfs(int x)
{
go(x, i)
if(!dep[to[i]])
{
dep[to[i]] = dep[x] + 1;
f[to[i]][0] = x;
dfs(to[i]);
}
}
int lca(int x, int y)
{
if(dep[x] != dep[y])
{
if(dep[y] > dep[x])
swap(x, y);
FOR(j, 19, 0)
if(dep[f[x][j]] > dep[y])
x = f[x][j];
x = f[x][0];
}
if(x == y)
return x;
FOR(j, 19, 0)
if(f[x][j] != f[y][j])
x = f[x][j], y = f[y][j];
if(x != y)
x = f[x][0];
return x;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1967.in", "r", stdin);
freopen("1967.out", "w", stdout);
#endif
int x, y;
scanf("%d%d", &n, &m);
For(i, 1, m)
scanf("%d%d%d", &E[i].x, &E[i].y, &E[i].z);
For(i, 1, n + m)
fa[i] = i;
sort(E + 1, E + m + 1, cmp);
For(i, 1, m)
{
int u = find(E[i].x), v = find(E[i].y);
if(u != v)
{
fa[u] = fa[v] = fa[i + n];
add(i + n, u), add(u, i + n);
add(i + n, v), add(v, i + n);
}
}
For(i, 1, m)
if(fa[n + i] == n + i)
dep[n + i] = 1, dfs(n + i);
For(j, 1, 19)
For(i, 1, n + m)
f[i][j] = f[f[i][j - 1]][j - 1];
scanf("%d", &q);
while(q --)
{
scanf("%d%d", &x, &y);
if(find(x) != find(y))
puts("-1");
else
printf("%d\n", E[lca(x, y) - n].z);
}
return 0;
}