题意:给出一张n个点m条边的无向图, 每条边有一个危险度,有q个询问, 每次给出两个点s、t,找一条路, 使得路径上的最大危险度最小
按秩合并并查集
不能路径压缩 否则就破坏了其树形结构

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v) memset(A,v,sizeof A)
typedef pair<int,int>pii;
//////////////////////////////////
const int N=1e6+10;
int f[N],x,y,q,n,m,siz[N],w[N];
struct Edge
{
int u,v,w;
}edge[N];
int find1(int x)
{
return f[x]==x?x:find1(f[x]);
}
void kruscal()
{
sort(edge+1,edge+1+m,[](Edge a,Edge b){return a.w<b.w;});
int cnt=0;
rep(i,1,n)f[i]=i,siz[i]=1;
CLR(w,0);
rep(i,1,m)
{
int x=find1(edge[i].u),y=find1(edge[i].v);
if(x==y)continue;
if(siz[x]<siz[y])
{
f[x]=y;
siz[y]=max(siz[y],siz[x]+1);
w[x]=edge[i].w;
}
else
{
f[y]=x;
siz[x]=max(siz[x],siz[y]+1);
w[y]=edge[i].w;
}
cnt++;
if(cnt==n-1)break;
}
}
int c[N];
int query(int x,int y)
{
rep(i,1,n)c[i]=-1;
int ans=0,temp=0;
while(1)
{
c[x]=temp;
if(f[x]==x)break;
temp=max(temp,w[x]);
x=f[x];
}
while(1)
{
if(c[y]>=0){ans=max(ans,c[y]);break;}//lca相同时就退出
if(f[y]==y)break;
ans=max(ans,w[y]);
y=f[y];
}
return ans;
}
int main()
{
int ok=0;
while(scanf("%d%d",&n,&m)==2)
{
if(ok)printf("\n");
ok=1;
rep(i,1,m)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
kruscal();
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y));
}
}
return 0;
}
