静态查询树上路径的最小边权
边权转点权: 将根节点设置 val[ rt ]=inf , 每个边权转移到向下的点的点权
然后树剖查询要改一下
树剖后用线段树查询点权最小值
#include <bits/stdc++.h>
using namespace std ;
const int N=5e5+4,M=N*2;
#define int long long
int n,nxt[M],hd[N],all,go[M],w[M];
int dep[N],sz[N],fa[N],son[N];
int dfn[N],id[N],pool,top[N];
void add_(int x,int y,int z){
go[++all]=y,w[all]=z,
nxt[all]=hd[x],hd[x]=all;
}
struct Edge{
int x,y,z;
}E[N];
int cmp(Edge &x,Edge &y){
return x.z>y.z;
}
int F[N];
int find(int x){
return x==F[x]?x:F[x]=find(F[x]);
}
void solve(int K){
sort(E+1,E+1+K,cmp);
for(int i=1;i<=K;i++){
int x=E[i].x,y=E[i].y,z=E[i].z;
int fx=find(E[i].x),fy=find(E[i].y);
if(fx!=fy){
add_(x,y,z); add_(y,x,z);
F[fy]=fx;
}
}
}
#define k1 k<<1
#define k2 k<<1|1
int vis[N],val[N] ;
int a[N];
struct Tree{
int v;
int l,r;
}tr[N<<2];
#define inf 1e18
int qry(int k,int x,int y){
int t=inf;
if(x<=tr[k].l&&y>=tr[k].r)
return tr[k].v;
int md=(tr[k].l+tr[k].r)/2;
if(x<=md) t=min(t,qry(k1,x,y));
if(y>md) t=min(t,qry(k2,x,y));
return t;
}
void build(int k,int l,int r){
tr[k].l=l,tr[k].r=r;
tr[k].v=inf;
if(l==r){
tr[k].v=val[id[l]]; return;
}
int md=(l+r)/2;
build(k1,l,md),build(k2,md+1,r);
tr[k].v=min(tr[k1].v,tr[k2].v);
}
void dfs1(int x,int par){
vis[x]=1;
n++;
fa[x]=par;
sz[x]=1;
dep[x]=dep[par]+1;
son[x]=0;
for(int i=hd[x];i;i=nxt[i]){
int y=go[i]; if(par==y) continue;
val[y]=w[i];
dfs1(y,x);
sz[x]+=sz[y];
if(sz[y]>sz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int topf){
dfn[x]=++pool;
id[pool]=x;
top[x]=topf;
if(!son[x]) return ;
dfs2(son[x],topf);
for(int i=hd[x];i;i=nxt[i]){
int y=go[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
int qRange(int x,int y){
if(find(x)!=find(y)) return inf;
int res=inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=min(res, qry(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(x==y) return res;
if(dep[x]>dep[y]) swap(x,y);
res=min(res, qry(1,dfn[x]+1,dfn[y])) ; //
return res;
}
signed main(){
int num,K;
int i,x,y,tes;
cin>>num>>K;
for(i=1;i<=num;i++) F[i]=i;
for(i=1;i<=K;i++)
cin>>E[i].x>>E[i].y>>E[i].z;
solve(K);
for(i=1;i<=num;i++){
if(vis[i]) continue;
val[i]=inf;
dfs1(i,0); dfs2(i,i);
}
build(1,1,n);
cin>>tes;
while(tes--){
cin>>x>>y;
int ans=qRange(x,y);if(ans==inf) ans=-1;
cout<<ans<<endl;
}
}
浙公网安备 33010602011771号