题面
这题没什么难度 一下就能想到最大生成树上跑 L C A LCA LCA 码量也不算是太大…
不多说了直接看代码吧…
#include<bits/stdc++.h>
using namespace std;
#define reg register
#define N 10050
#define M 500050
#define QAQ puts("QAQ");
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int n,m,q,x,y,tot,cnt,fa[N],dep[N],head[N],f[N][17],w[N][17];
bool vis[N];
struct nodekru{
int st,to,val;
}e[M];
struct node{
int to,nxt,val;
}edge[M<<1];
bool cmp(nodekru a, nodekru b){
return a.val>b.val;
}
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
inline void addedge(int u, int v, int w){
edge[++tot].to=v,edge[tot].nxt=head[u];
edge[tot].val=w,head[u]=tot;
}
inline void superadd(int u, int v, int w){
addedge(u,v,w),addedge(v,u,w);
}
void kruscal(){
sort(e+1,e+1+m,cmp);
for(reg int i=1;i<=m;i++){
int uu=find(e[i].st),vv=find(e[i].to);
if(uu==vv)continue;
fa[uu]=vv;
superadd(e[i].st,e[i].to,e[i].val);
}
}
void pretreat(int u, int fa){
vis[u]=true;
for(reg int i=1;i<=16;i++)
f[u][i]=f[f[u][i-1]][i-1],w[u][i]=min(w[f[u][i-1]][i-1],w[u][i-1]);
for(reg int i=head[u];i;i=edge[i].nxt){
int vv=edge[i].to;
if(vis[vv])continue;
w[vv][0]=edge[i].val;
dep[vv]=dep[u]+1;
f[vv][0]=u;
pretreat(vv,u);
}
}
int lca(int x, int y){
if(find(x)!=find(y))return -1;
int nans=0x7f7f7f7f;
if(dep[x]<dep[y])swap(x,y);
for(reg int i=16;~i;i--)if(dep[f[x][i]]>=dep[y])nans=min(nans,w[x][i]),x=f[x][i];
if(x==y)return nans;
for(reg int i=16;~i;i--)if(f[x][i]!=f[y][i])nans=min(nans,min(w[x][i],w[y][i])),x=f[x][i],y=f[y][i];
return min(nans,min(w[x][0],w[y][0]));
}
int main(){
read(n),read(m);
for(int i=1;i<=n;i++)fa[i]=i;
for(reg int i=1;i<=m;i++)read(e[i].st),read(e[i].to),read(e[i].val);
kruscal();
for(reg int i=1;i<=n;i++){
if(!vis[i]){
dep[i]=1;
pretreat(i,i);
w[i][0]=0x7f7f7f7f;
}
}
read(q);
for(reg int i=1;i<=q;i++){
read(x),read(y);
printf("%d\n",lca(x,y));
}
}