P2245 星际导航
//基于倍增的LCA + kruskal重构树 + 并查集
#include<bits/stdc++.h>
#define endl '\n'
#define rep(_start_,_end_) for(int i = _start_;i <= (_end_);i ++)
#define all0(x) (x).begin(),(x).end()
#define all1(x) (x).begin() + 1,(x).end()
using namespace std;
using ll = long long;
const int N = 1e5 + 10; // 原图最大顶点数
const int M = 5e5 + 10; // 原图最大边数
int n, m, q;
int par[N * 2];
int val[N * 2];//非叶子的权值
vector<int>trie[N * 2];
struct EDGE
{
int u, v, w;
};
int Find(int x)
{
return (par[x] == x) ? x : par[x] = Find(par[x]);
}
int new_node;
void build_kruskal(vector<EDGE>&edge)
{
//初始化
for(int i = 1;i <= 2 * n - 1;i ++)
par[i] = i;
//遍历所有边
new_node = n;
for(auto &[l,r,w] : edge)
{
int rootl = Find(l);
int rootr = Find(r);
if(rootl != rootr)
{
new_node ++;
val[new_node] = w;
// cout << "newnode: "<<new_node <<endl;
trie[new_node].push_back(rootl);
trie[new_node].push_back(rootr);
par[rootl] = new_node;
par[rootr] = new_node;
}
}
}
int dep[N * 2],fa[N * 2][20];
void dfs(int u,int u_father)
{
dep[u] = dep[u_father] + 1;
fa[u][0] = u_father;
for(int j = 1;j <= 19;j ++)
{
fa[u][j] = fa[fa[u][j - 1]][j - 1];
}
for(auto v:trie[u])
{
if(v != u_father)
{
dfs(v,u);
}
}
}
int get_lca(int l,int r)
{
if(dep[l] < dep[r])swap(l,r);
for(int i = 19;i >= 0;i --)
{
if(dep[fa[l][i]] >= dep[r])
l = fa[l][i];
}
if(l == r)return l;
for(int i = 19;i >= 0;i --)
{
if(fa[l][i] != fa[r][i])
l = fa[l][i],r = fa[r][i];
}
return fa[l][0];
}
void solve()
{
cin >> n >> m;
vector<EDGE> edge(m);
rep(0, m - 1) cin >> edge[i].u >> edge[i].v >> edge[i].w;
sort(all0(edge), [](const auto&i, const auto&j){
return i.w < j.w;
});
//重构树
build_kruskal(edge);
//预处理dfs
for(int i = 1;i <= new_node ;i ++)
{
if(par[i] == i)
{
dfs(i,0);
}
}
// for(int i = 1;i <= 2 * n - 1;i ++)cout << fa[i][0]<<" ";
// cout << endl;
cin >> q;
while(q --)
{
int l,r;
cin >> l >> r;
if(Find(l) != Find(r))
cout << "impossible"<<endl;
else{
cout << val[get_lca(l,r)] <<endl;
}
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
// cin >> t;
t = 1;
while(t --)
{
solve();
}
return 0;
}