LCA入門題————————————————————————————————————————————-
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,q,hd[10005],cnt,fa[10005],dep[10005],ru[10005],rt;
int xa,ya,f[10005][20],w[10005][20];
struct nod{
int x,y,z;
}a[10005];//
struct Edge{
int to,nxt,w;
}eg[20005];
bool cmp(nod p,nod q)
{
return p.z>q.z;
}
int find(int x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void add(int x,int y,int z)
{
cnt++;
eg[x].to=y;
eg[x].w=z;
eg[x].nxt=hd[x];
hd[x]=cnt;
}
void krus()
{
for(int i=1;i<=n;i++)
fa[i]=i;
sort(a+1,a+m+1,cmp);
for(int i=1;i<=m;i++)
{
int u=find(a[i].x);
int v=find(a[i].y);
if(u!=v)
{
fa[v]=u;ru[v]++;
//重新建圖
add(a[i].x,a[i].y,a[i].z);
add(a[i].y,a[i].x,a[i].z);
}
if(cnt==n-1) break;//最大生成樹建立成功
}
}
void dfs(int u,int d)
{
dep[u]=d;
for(int i=hd[u];i;i=eg[i].nxt)
{
int v=eg[i].to;
if(v!=f[u][0])//兒子不是自己的父親
{
f[v][0]=u;
w[v][0]=eg[i].w;
dfs(v,d+1);
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int s=0x3f3f3f3f;
for(int i=20;i>=0;i--)
{
if(dep[x]>dep[y])
{
s=min(s,w[x][i]);
x=f[x][i];
}
}
if(x==y) return s;
for(int i=20;i>=0;i++)
if(f[x][i]!=f[y][i])
{
s=min(s,min(w[x][i],w[y][i]));
x=f[x][i];
y=f[y][i];
}
s=min(s,min(w[x][0],w[y][0]));
return s;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a[i].x,&a[i].y,&a[i].z);
}
krus();//建立一棵樹,最大生成樹
for(int i=1;i<=n;i++){
if(ru[i]==0) {
rt=i;break;
}
}
dfs(rt,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=20;j++)
{
f[i][j]=f[f[i][j-1]][j-1];//i向上跳j步=i,f[i][j]向上跳j-1步
w[i][j]=min(w[i][j-1],w[f[i][j-1]][j-1]);
}
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&xa,&ya);
if(find(xa)!=find(ya))
printf("%d\n",-1);
else
printf("%d\n",lca(xa,ya));
}
}