题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4366
题目大意:求一个结点的子树中能力值大于它且忠诚值最大的结点是哪个。
题目思路:线段树,按能力值由大到小加入线段树,能力值相同时先加id小的,这样能保证不会有能力值和父亲相同的儿子加到父亲前面,这样每次查询就能得到答案,由于忠诚值不同,可以进行hash或用map。话说数据好水啊,错误代码都能过。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define M 50010
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int eid,st[M],ed[M],ab[M],lo[M],p[M],stamp,rec,id[M],ans[M];
int mp[1010000];
struct node
{
int to,next;
}e[2*M];
struct nn
{
int l,r,ma;
int mid()
{
return (l+r)>>1;
}
}T[4*M];
bool cmp(int a,int b)
{
if(ab[a]==ab[b])
return a<b;
return ab[a]>ab[b];
}
void addedge(int u,int v)
{
e[eid].to=v;
e[eid].next=p[u];
p[u]=eid++;
}
void dfs(int u)
{
int i,v;
st[u]=stamp++;
for(i=p[u];i!=-1;i=e[i].next)
{
v=e[i].to;
dfs(v);
}
ed[u]=stamp-1;
}
void build(int l,int r,int rt)
{
T[rt].l=l;T[rt].r=r;
T[rt].ma=-inf;
if(l==r) return;
int mid=T[rt].mid();
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
}
void modify(int x,int rt,int data)
{
if(T[rt].l==T[rt].r)
{
T[rt].ma=data;
return;
}
int mid=T[rt].mid();
if(x<=mid)
modify(x,rt<<1,data);
else
modify(x,rt<<1|1,data);
T[rt].ma=max(T[rt<<1].ma,T[rt<<1|1].ma);
}
void query(int l,int r,int rt)
{
if(l==T[rt].l&&r==T[rt].r)
{
rec=max(rec,T[rt].ma);
return ;
}
int mid=T[rt].mid();
if(r<=mid)
query(l,r,rt<<1);
else if(l>mid) query(l,r,rt<<1|1);
else
{
query(l,mid,rt<<1);
query(mid+1,r,rt<<1|1);
}
}
int main()
{
int i,u,t,n,m,x;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
eid=0;
stamp=0;
memset(mp,0,sizeof(mp));
memset(p,-1,sizeof(p));
for(i=1;i<n;i++)
{
scanf("%d%d%d",&u,&lo[i],&ab[i]);
id[i]=i;
mp[lo[i]]=i;
addedge(u,i);
}
sort(id+1,id+n,cmp);
dfs(0);
build(0,n-1,1);
for(i=1;i<n;i++)
{
if(st[id[i]]==ed[id[i]])
{
ans[id[i]]=-1;
}
else
{
rec=-inf;
query(st[id[i]]+1,ed[id[i]],1);
if(rec==-inf) ans[id[i]]=-1;
else
{
ans[id[i]]=mp[rec];
}
}
modify(st[id[i]],1,lo[id[i]]);
}
for(i=0;i<m;i++)
{
scanf("%d",&x);
printf("%d\n",ans[x]);
}
}
}