Successor
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1779 Accepted Submission(s): 426
Problem Description
Sean owns a company and he is the BOSS.The other Staff has one Superior.every staff has a loyalty and ability.Some times Sean will fire one staff.Then one of the fired man’s Subordinates will replace him whose ability is higher than him and has the highest loyalty for company.Sean want to know who will replace the fired man.
Input
In the first line a number T indicate the number of test cases. Then for each case the first line contain 2 numbers n,m (2<=n,m<=50000),indicate the company has n person include Sean ,m is the times of Sean’s query.Staffs are numbered from 1 to n-1,Sean’s number is 0.Follow n-1 lines,the i-th(1<=i<=n-1) line contains 3 integers a,b,c(0<=a<=n-1,0<=b,c<=1000000),indicate the i-th staff’s superior Serial number,i-th staff’s loyalty and ability.Every staff ‘s Serial number is bigger than his superior,Each staff has different loyalty.then follows m lines of queries.Each line only a number indicate the Serial number of whom should be fired.
Output
For every query print a number:the Serial number of whom would replace the losing job man,If there has no one to replace him,print -1.
Sample Input
1 3 2 0 100 99 1 101 100 1 2
Sample Output
2 -1
Author
FZU
Source
Recommend
zhuyuanchen520
思路:用dfs时间戳将树转成线性的,然后建立线段树,查找忠诚度最高的员工,查找的范围就是子树所化的时间戳,能力值需要排序,从大到小查找,就可以不管能力这个属性了。
有个注意点,当能力值一样时应该选查找上司,再查下属,这样就不会出现不符合的情况
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<map> 5 #include<algorithm> 6 #define lson t<<1 7 #define rson t<<1|1 8 #define mid (l+r)/2 9 using namespace std; 10 const int mm=5e4+9; 11 map<int,int>mp; 12 int L[mm],R[mm]; 13 int cas,head[mm],edge,n,m; 14 class node 15 { 16 public:int v,next; 17 }e[mm+mm]; 18 class ppeo 19 { 20 public:int u,loy,abi,no; 21 bool operator <(const ppeo &xx)const 22 { 23 if(abi^xx.abi) 24 return abi>xx.abi; 25 return no<xx.no;///这个很关键,这会排除能力值一样的上司和员工,上司先查 26 } 27 }f[mm]; 28 class Tree 29 { 30 public:int l,r,mloy; 31 }rt[mm*4]; 32 int dfs_clock; 33 int ans[mm]; 34 void data() 35 { 36 memset(head,-1,sizeof(head));edge=0; 37 } 38 void add(int u,int v) 39 { 40 e[edge].v=v;e[edge].next=head[u];head[u]=edge++; 41 } 42 void build(int t,int l,int r) 43 { 44 rt[t].l=l;rt[t].r=r;rt[t].mloy=-1; 45 if(l==r)return; 46 build(lson,l,mid);build(rson,mid+1,r); 47 } 48 void dfs(int u) 49 { L[u]=dfs_clock; 50 for(int i=head[u];~i;i=e[i].next) 51 { ++dfs_clock; 52 dfs(e[i].v); 53 } 54 R[u]=dfs_clock; 55 } 56 int query(int t,int l,int r) 57 { 58 if(rt[t].l==l&&rt[t].r==r)return rt[t].mloy; 59 if(rt[lson].r>=r)return query(lson,l,r); 60 else if(rt[rson].l<=l)return query(rson,l,r); 61 else return max(query(lson,l,rt[lson].r),query(rson,rt[rson].l,r)); 62 } 63 void update(int t,int pos,int x) 64 { 65 if(rt[t].l==rt[t].r&&rt[t].l==pos){rt[t].mloy=x;return ;} 66 if(rt[lson].r>=pos)update(lson,pos,x); 67 else update(rson,pos,x); 68 rt[t].mloy=max(rt[lson].mloy,rt[rson].mloy); 69 } 70 int main() 71 { int a,b,c; 72 while(~scanf("%d",&cas)) 73 { 74 while(cas--) 75 { data(); 76 mp.clear(); 77 scanf("%d%d",&n,&m); 78 for(int i=1;i<n;++i) 79 { 80 scanf("%d%d%d",&a,&b,&c); 81 add(a,i);f[i].loy=b;f[i].abi=c;f[i].no=i; 82 mp[b]=i;///忠诚度唯一 83 } 84 dfs_clock=0; 85 dfs(0); 86 sort(f+1,f+n); 87 build(1,0,dfs_clock);///建树 88 int z; 89 memset(ans,-1,sizeof(ans)); 90 for(int i=1;i<n;++i) 91 { 92 z=query(1,L[f[i].no],R[f[i].no]); 93 if(z!=-1)///查到了后代的最大忠诚度 94 { 95 ans[f[i].no]=mp[z]; 96 } 97 update(1,L[f[i].no],f[i].loy); 98 } 99 for(int i=0;i<m;++i) 100 { 101 scanf("%d",&a); 102 printf("%d\n",ans[a]); 103 } 104 } 105 } 106 return 0; 107 }