静态查询树上路径的最小边权
边权转点权: 将根节点设置 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; } }