這是一道經典的Kruskal重構樹的題目,仍是得好好寫寫,
題目中html
每組詢問詢問從點v開始只通過困難值小於等於x的路徑所能到達的山峯中第k高的山峯c++
中ui
從點v開始只通過困難值小於等於x的路徑spa
難以實現
因此咱們要藉助Kruskal重構樹的黑科技,
建一顆Kruskal重構樹,
若有不會的敬請請看這裏
而後每次詢問從一個點往上倍增跳,跳到不能跳爲止
這個點如下的點就是能經過困難值<=x的邊能到達的點,
根據Kruskal重構樹的性質,全部原來節點都在葉子節點,每次查詢這個點所表明的葉子區間中第k大值
k大值,用主席樹維護便可code
#include<bits/stdc++.h> #define lc son[x][0] #define rc son[x][1] using namespace std; const int N=3e5+6,M=27; int n,m,Q,tot,cnt=0,num=0,head[N<<1],h[N],f[N<<1],rt[N]; int fa[N<<1][22],maxx[N<<1][22],fst[N<<1],lat[N<<1]; int t1,t2,t3,amt=0,siz,a[N],son[N*20][2],sum[N*20]; struct que{int x,y,z;}q[N]; struct edge{int nxt,to;}e[N<<1]; inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v,head[u]=cnt;} inline int read(){ int T=0,F=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();} while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar(); return F*T; } bool cmp(que u,que v){return u.z<v.z;} int getf(int u){return f[u]==u?u:f[u]=getf(f[u]);} bool merge(int u,int v,int w){ u=getf(u),v=getf(v); if(u==v) return false; ++tot,f[u]=f[v]=f[tot]=tot,add(tot,u),add(tot,v); fa[u][0]=fa[v][0]=tot,maxx[u][0]=maxx[v][0]=w; return true; } void build(int l,int r,int &x){ x=++num; int mid=l+r>>1; if(l==r) return; build(l,mid,lc),build(mid+1,r,rc); sum[x]=sum[lc]+sum[rc]; } void update(int l,int r,int p,int &x,int y){ if(!x) x=++num; sum[x]=sum[y]+1; if(l==r) return; int mid=l+r>>1; if(p<=mid) rc=son[y][1],update(l,mid,p,lc,son[y][0]); else lc=son[y][0],update(mid+1,r,p,rc,son[y][1]); } int query(int l,int r,int p,int x,int y){ if(l==r) return l; int mid=l+r>>1,o=-sum[rc]+sum[son[y][1]]; if(p>o) return query(l,mid,p-o,lc,son[y][0]); else return query(mid+1,r,p,rc,son[y][1]); } void dfs(int x){ for(int i=1;i<=20;++i) fa[x][i]=fa[fa[x][i-1]][i-1],maxx[x][i]=max(maxx[x][i-1],maxx[fa[x][i-1]][i-1]); fst[x]=amt; if(!head[x]) ++amt,fst[x]=amt,t1=lower_bound(a+1,a+siz+1,h[x])-a,update(1,siz,t1,rt[amt],rt[amt-1]); for(int i=head[x];i;i=e[i].nxt) dfs(e[i].to); lat[x]=amt; } int main(){ n=read(),m=read(),Q=read(),tot=n; for(int i=1;i<=n;++i) h[i]=read(),f[i]=i,a[i]=h[i]; for(int i=1;i<=m;++i) q[i].x=read(),q[i].y=read(),q[i].z=read(); sort(q+1,q+m+1,cmp),sort(a+1,a+n+1),siz=unique(a+1,a+n+1)-a-1; for(int i=1;i<n;++i){ ++num; if(num>m) break; if(!merge(q[num].x,q[num].y,q[num].z)) --i; } num=0,build(1,siz,rt[0]),dfs(tot); for(int i=1;i<=Q;++i){ t1=read(),t2=read(),t3=read(); for(int j=20;j>=0;--j) if(fa[t1][j]&&t2>=maxx[t1][j]) t1=fa[t1][j]; if(sum[rt[lat[t1]]]-sum[rt[fst[t1]]]<t3) printf("-1\n"); else printf("%d\n",a[query(1,siz,t3,rt[fst[t1]],rt[lat[t1]])]); } return 0; }