正题
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3732
题目大意
一张图,每次询问两个点,求这两个点之间路径的最大值的最小是多少。
解题思路
构造一颗 重构树然后就是模板了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+10;
struct node{
int x,y,w;
}e[N];
struct edge_node{
int to,next;
}a[N];
int n,m,k,tot,cnt,root,ls[N],val[N];
int top[N],dep[N],siz[N],son[N],fa[N];
void addl(int x,int y)
{
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;
}
bool cmp(node x,node y)
{return x.w<y.w;}
int find(int x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
void dfs1(int x)
{
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa[x]) continue;
dep[y]=dep[x]+1;fa[y]=x;
dfs1(y);siz[x]+=siz[y];
if(siz[y]>siz[son[x]])
son[x]=y;
}
}
void dfs2(int x)
{
if(son[x]){
top[son[x]]=top[x];
dfs2(son[x]);
}
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa[x]||y==son[x]) continue;
top[y]=y;dfs2(y);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y]) return x;
else return y;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
for(int i=1;i<=n+m;i++)
fa[i]=i;
sort(e+1,e+1+m,cmp);cnt=n;
for(int i=1;i<=m;i++){
int fx=find(e[i].x),fy=find(e[i].y);
if(fx!=fy){
fa[fy]=fa[fx]=++cnt;
addl(cnt,fx);addl(cnt,fy);
addl(fx,cnt);addl(fy,cnt);
val[cnt]=e[i].w;
}
}
root=find(1);
dfs1(root);top[root]=root;dfs2(root);
for(int i=1;i<=k;i++){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",val[LCA(x,y)]);
}
}