【题意分析】
知识点:kruskal重构树
构建重构树的过程:kruskal时,将边上的端点全都和一个虚点相连,这个点的点权就是原来的边权。
性质:重构树上的LCA就是两边所有路径危险值最大的最小值。
Code:
//KajKeusaka
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 300000
using namespace std;
struct fls {int to, next;} edge[MAXN << 1];
struct Node {int x, y, v;} data[MAXN];
int top[MAXN], head[MAXN << 1], f[MAXN], father[MAXN], depth[MAXN];
int size[MAXN], son[MAXN], val[MAXN], n, m, cnt, Cnt;
inline int read () {
register int s = 0, w = 1;
register char ch = getchar ();
while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
return s * w;
}
int getfather (int x) {return (x == f[x]) ? x : f[x] = getfather (f[x]);}
inline void connect2 (int u, int v) {edge[++Cnt].to = v, edge[Cnt].next = head[u], head[u] = Cnt;}
inline bool cmp (Node a, Node b) {return a.v < b.v;}
inline int LCA (int x, int y) {
while (top[x] != top[y]) {
if (depth[top[x]] < depth[top[y]]) swap (x, y);
x = father[top[x]];
}
return (depth[x] > depth[y]) ? y : x;
}
void DFS1 (int now, int fa, int d) {
depth[now] = d, father[now] = fa, size[now] = 1; int maxson = -1;
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to; if (v == fa) continue;
DFS1 (v, now, d + 1), size[now] += size[v];
if (size[v] > maxson) {son[now] = v, maxson = size[v];}
}
}
void DFS2 (int now, int top_heavy) {
top[now] = top_heavy; if (! son[now]) return;
DFS2 (son[now], top_heavy);
for (register int i = head[now]; i; i = edge[i].next) {
int v = edge[i].to;
if (v != father[now] && v != son[now]) DFS2 (v, v);
}
}
int main () {
n = read (), m = read ();
for (register int i = 1; i <= m; i++)
data[i].x = read (), data[i].y = read (), data[i].v = read ();
sort (data + 1, data + m + 1, cmp); int now = n;
for (register int i = 1; i <= n * 2; i++) f[i] = i;
for (register int i = 1; i <= m; i++) {
int x = data[i].x, y = data[i].y;
int xx = getfather (x), yy = getfather (y);
if (xx != yy) {
f[xx] = f[yy] = ++now;
connect2 (xx, now), connect2 (now, xx),
connect2 (yy, now), connect2 (now, yy);
val[now] = data[i].v;
}
}
for (register int i = now; i; i--)
if (! depth[i]) DFS1 (i, 0, 1), DFS2 (i, i);
int q = read ();
for (register int I = 1; I <= q; I++) {
int u = read (), v = read ();
if (getfather (u) != getfather (v)) puts ("impossible");
else printf ("%d\n", val[LCA (u, v)]);
}
return 0;
}
/*
4 5
1 2 5
1 3 2
2 3 11
2 4 6
3 4 4
3
2 3
1 4
1 2
*/