做法:离线+线段树合并
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5,M=1e9;
int n,m,q,h,fa[100005],rt[100005],tr[N],ls[N],rs[N],tot;
void update(int &cur,int l,int r,int loc){
tr[cur=++tot]=1;
if(l==r)return ;
int mid=(l+r)>>1;
if(loc<=mid)update(ls[cur],l,mid,loc);
else update(rs[cur],mid+1,r,loc);
return ;
}
int ff(int u){return fa[u]==u?u:fa[u]=ff(fa[u]);}
int merge(int u,int v){
if(!u || !v)return u|v;
ls[u]=merge(ls[u],ls[v]);
rs[u]=merge(rs[u],rs[v]);
tr[u]=tr[ls[u]]+tr[rs[u]];
return u;
}
int query(int &cur,int l,int r,int val){
if(!cur)cur=++tot;
if(l==r)return l;
int mid=(l+r)>>1;
if(val>tr[rs[cur]])return query(ls[cur],l,mid,val-tr[rs[cur]]);
else return query(rs[cur],mid+1,r,val);
}
struct node{
int u,v,w;
}e[500005],qs[500005];
bool operator <(const node &x,const node &y){return x.w<y.w;}
int main(){
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++){
scanf("%d",&h);
update(rt[i],1,M,h);
fa[i]=i;
}
for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+1,e+m+1);
for(int i=1;i<=q;i++)scanf("%d%d%d",&qs[i].u,&qs[i].w,&qs[i].v);
sort(qs+1,qs+q+1);
for(int i=1,j=1;i<=q;i++){
while(j<=m && e[j].w<=qs[i].w){
int u=ff(e[j].u),v=ff(e[j].v);
if(u!=v)fa[v]=u,merge(rt[u],rt[v]);
j++;
}
int u=ff(qs[i].u);
printf("%d\n",tr[rt[u]]<qs[i].v?-1:query(rt[u],1,M,qs[i].v));
}
return 0;
}