题面
原题
Solution
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<queue>
#include<algorithm>
#define ll long long
#define re register
using namespace std;
inline int gi(){
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=10010,M=50010;
int to[M<<1],nxt[M<<1],w[M<<1],front[N],cnt;
int dep[N],f[N][20],val[N][20],father[N],n,m;
struct E{
int u,v,w;
}edge[M];
void Add(int u,int v,int W){
to[++cnt]=v;nxt[cnt]=front[u];front[u]=cnt;
w[cnt]=W;
}
void dfs(int u,int fa){
dep[u]=dep[fa]+1;f[u][0]=fa;
for(re int i=front[u];i;i=nxt[i]){
int v=to[i];
if(v!=fa){
val[v][0]=w[i];
dfs(v,u);f[v][0]=u;
}
}
}
int lca(int u,int v){
int ans=2e9;
if(dep[u]<dep[v])swap(u,v);
for(int i=15;~i;--i)
if(dep[u]-(1<<i)>=dep[v]){
ans=min(ans,val[u][i]);
u=f[u][i];
}
if(u==v)return ans;
for(re int i=15;~i;i--)
if(f[u][i]!=f[v][i]){
ans=min(ans,min(val[v][i],val[u][i]));
u=f[u][i],v=f[v][i];
}
ans=min(ans,min(val[u][0],val[v][0]));
return ans;
}
int find(int x){
if(father[x]!=x)father[x]=find(father[x]);
return father[x];
}
bool cmp(E a,E b){
return a.w>b.w;
}
int main(){
n=gi();m=gi();
for(re int i=1;i<=m;i++){
int u=gi(),v=gi(),w=gi();
edge[i]=(E){u,v,w};
}
sort(edge+1,edge+m+1,cmp);
for(re int i=1;i<=n;i++)father[i]=i;
for(re int i=1;i<=m;i++){
int u=find(edge[i].u),v=find(edge[i].v);
if(u!=v){
father[v]=u;
Add(edge[i].u,edge[i].v,edge[i].w);
Add(edge[i].v,edge[i].u,edge[i].w);
}
}
for(re int i=1;i<=n;i++)
if(!f[i][0]){
dfs(i,i);val[i][0]=2e9;f[i][0]=i;
}
for(re int i=1;i<=15;i++)
for(re int j=1;j<=n;j++){
f[j][i]=f[f[j][i-1]][i-1];
val[j][i]=min(val[f[j][i-1]][i-1],val[j][i-1]);
}
int q=gi();
while(q--){
int u=gi(),v=gi();
if(find(u)!=find(v)){
printf("%d\n",-1);continue;
}
printf("%d\n",lca(u,v));
}
return 0;
}