题面
题解
(kruskal)重构树板子题??(大雾
因为重构树上两点之间的(LCA)的权值就是原图上最小生成树上的瓶颈。
所以建个重构树,跑(LCA)即可。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
inline int read()
{
int data = 0, w = 1;
char ch = getchar();
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}
const int maxn(2e5 + 10), maxm(3e5 + 10);
struct edge { int next, to; } e[maxn << 2];
struct Edge { int from, to, dis; } E[maxm];
inline bool cmp(const Edge &lhs, const Edge &rhs) { return lhs.dis < rhs.dis; }
int fa[maxn], f[maxn], size[maxn], belong[maxn], heavy[maxn], head[maxn], e_num, cnt, pos[maxn], val[maxn], n, m, n_cnt;
inline void add_edge(int from, int to) { e[++e_num] = (edge) {head[from], to}; head[from] = e_num; }
void dfs(int x)
{
size[x] = 1;
for(RG int i = head[x]; i; i = e[i].next)
{
int to = e[i].to; if(to == fa[x]) continue;
fa[to] = x; dfs(to); size[x] += size[to];
if(size[heavy[x]] < size[to]) heavy[x] = to;
}
}
void dfs(int x, int chain)
{
pos[x] = ++cnt; belong[x] = chain;
if(!heavy[x]) return;
dfs(heavy[x], chain);
for(RG int i = head[x]; i; i = e[i].next)
{
int to = e[i].to; if(to == fa[x] || to == heavy[x]) continue;
dfs(to, to);
}
}
inline int LCA(int a, int b)
{
while(belong[a] != belong[b])
{
if(pos[belong[a]] < pos[belong[b]]) std::swap(a, b);
a = fa[belong[a]];
}
return pos[a] < pos[b] ? a : b;
}
inline int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
inline void Kruskal()
{
std::sort(E + 1, E + m + 1, cmp); n_cnt = n;
for(RG int i = 1; i <= m; i++)
{
int fx = find(E[i].from), fy = find(E[i].to);
if(fx == fy) continue;
f[fx] = f[fy] = ++n_cnt; f[n_cnt] = n_cnt;
add_edge(n_cnt, fx); add_edge(fx, n_cnt);
add_edge(n_cnt, fy); add_edge(fy, n_cnt);
val[n_cnt] = E[i].dis;
}
for(RG int i = n_cnt; i; i--)
if(!pos[i]) dfs(i), dfs(i, i);
}
int main()
{
#ifndef ONLINE_JUDGE
file(cpp);
#endif
n = read(); m = read();
for(RG int i = 1; i <= m; i++) E[i] = (Edge) {read(), read(), read()};
for(RG int i = 1; i <= n; i++) f[i] = i;
RG int q = read(); Kruskal();
while(q--)
{
int a = read(), b = read();
if(find(a) != find(b)) puts("impossible");
else printf("%d
", val[LCA(a, b)]);
}
return 0;
}