输出全是-1,有理由怀疑是并查集,但是手推的时候并没有出错(悲
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+5,maxm = 20;
const int inf = 1e9+5;
int n,m,q,pos,ans(inf);
int c[maxn][maxm],f[maxn][maxm],d[maxn];
int fa[maxn];
vector<pair<int,int> >g[maxn];
struct Edge{
int x,y,value;
bool operator < (const Edge& x) const {
return value > x.value;
}
}res[maxn];
priority_queue<Edge>que;
bool find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
void dfs(int u,int fa){
d[u] = d[fa] + 1;
f[u][0] = fa;
c[u][0] = min(u,fa);
for(int i = 1;i<20;i++){
f[u][i] = f[f[u][i-1]][i-1];
c[u][i] = min(c[u][i-1],c[f[u][i-1]][i-1]);
}
for(auto i : g[u]){
if(i.first==fa)continue;
int v = i.first,w = i.second;
c[v][0] = w;
dfs(i.first,u);
}
}
int lca(int u,int v){
if(d[u] < d[v])swap(u,v);
for(int i = maxm - 1;i>=0;i--){
if(d[f[u][i]]>=d[v]){
ans = min(ans,c[u][i]);
u = f[u][i];
}
}
if(u==v)return u;
for(int i = maxm - 1;i>=0;i--){
if(f[u][i]!=f[v][i]){
ans = min({c[u][i],c[v][i],ans});
u = f[u][i];
v = f[v][i];
}
}
return min({c[u][0],c[v][0],ans});
}
int main(){
cin>>n>>m;
for(int i = 1,x,y,z;i<=m;i++){
cin>>x>>y>>z;
que.push({x,y,z});
}
//kruskal
for(int i = 1;i<=n;i++)fa[i] = i;
for(int i = 1;i<=m;i++){
Edge tmp = que.top();
que.pop();
int fx = find(tmp.x);
int fy = find(tmp.y);
if(fx==fy)continue;
fa[fx] = fy;
ans += tmp.value;
res[++pos] = tmp;
//存边
}
//建树
for(int i = 1,x,y,z;i<=pos;i++){
x = res[i].x;
y = res[i].y;
g[x].push_back({y,z});
g[y].push_back({x,z});
}
for(int i = 1;i<=n;i++){
if(!d[i])dfs(i,0);
}
cin>>q;
for(int i = 1,u,v;i<=q;i++){
cin>>u>>v;
if(fa[u]!=fa[v])cout<<-1<<'\n';
else{
cout<<lca(u,v)<<'\n';
}
}
//N-5保佑
}