码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3974 Assign the task(线段树 时间戳)

时间:2017-10-05 22:36:29      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:set   链接   分配   pre   --   color   eof   names   cto   

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3974

题意:n名员工组成一棵树,分配任务给其中一名员工,那么他和他的手下(就是该节点的全部子节点们)就要开始做这项任务,询问其中一个员工

输出他正在进行任务

题解:题目给我们的是两两员工的关系(其中一个是另一个的上司),整一个树。因为数据原因,用线段树去实现,要形成区间,这时候我们可以用dfs

给每个员工打上时间戳,形成区间代表最前面的那个上司统领员工(区间长度表示统领的员工数),然后就可以用线段树去处理了、

  1 #include <vector>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 using namespace std;
  7 
  8 const int N=50010;
  9 
 10 int st[N],en[N];
 11 int index;
 12 bool used[N];
 13 vector <int> E[N];
 14 
 15 void dfs(int k){
 16     st[k]=++index;
 17     int len=E[k].size();
 18     for(int i=0;i<len;i++) dfs(E[k][i]);
 19     en[k]=index;
 20 }
 21 
 22 struct Tree
 23 {
 24     int l,r,task;
 25     bool vis;
 26 };
 27 Tree tree[4*N];
 28 
 29 void pushdown(int x) 
 30 {
 31     int tmp=x<<1;
 32     if(tree[x].l!=tree[x].r){
 33          tree[tmp].vis=tree[tmp+1].vis=1;
 34         tree[tmp].task=tree[tmp+1].task=tree[x].task;
 35         tree[x].vis=0;    
 36     }   
 37 }
 38 
 39 void build(int l,int r,int x)
 40 {
 41     tree[x].l=l;tree[x].r=r;
 42     tree[x].task=-1;tree[x].vis=0;
 43     if(l==r) return ;    
 44     int tmp=x<<1;
 45     int mid=(l+r)>>1;
 46     build(l,mid,tmp);
 47     build(mid+1,r,tmp+1);
 48 }
 49 
 50 void update(int l,int r,int c,int x)
 51 {
 52     if(r<tree[x].l||l>tree[x].r) return ;
 53     if(l==tree[x].l&&r==tree[x].r)
 54     {
 55         tree[x].task=c;
 56         tree[x].vis=1;
 57         return ;    
 58     }
 59     if(tree[x].vis) pushdown(x);
 60     int tmp=x<<1;
 61     int mid=(tree[x].l+tree[x].r)>>1;
 62     if(r<=mid) update(l,r,c,tmp);
 63     else if(l>mid) update(l,r,c,tmp+1);
 64     else
 65     {
 66         update(l,mid,c,tmp);
 67         update(mid+1,r,c,tmp+1);    
 68     }
 69 }
 70 
 71 int query(int k,int x)
 72 {
 73     if(k==tree[x].l&&k==tree[x].r) return tree[x].task;
 74     if(tree[x].vis) pushdown(x);    
 75     int tmp=x<<1;
 76     int mid=(tree[x].l+tree[x].r)>>1;
 77     if(k<=mid) query(k,tmp);
 78     else if(k>mid) query(k,tmp+1);
 79 }
 80 
 81 int main(){
 82     int t,n,u,v,m,Case=1;
 83     char op[10];
 84     scanf("%d",&t);
 85     while(t--){
 86         memset(used,0,sizeof(used));
 87         scanf("%d",&n);
 88         for(int i=1;i<=n;i++) E[i].clear();
 89         for(int i=1;i<n;i++){
 90             scanf("%d%d",&u,&v);
 91             E[v].push_back(u);
 92             used[u]=1;
 93         }
 94         index=0;
 95         for(int i=1;i<=n;i++){
 96             if(!used[i]) {dfs(i);break;}
 97         }
 98         printf("Case #%d:\n",Case++);
 99         build(1,n,1);
100         scanf("%d",&m);
101         while(m--){
102             scanf("%s",op);
103             if(op[0]==C){
104                 scanf("%d",&u);
105                 printf("%d\n",query(st[u],1));
106             }
107             else if(op[0]==T){
108                 scanf("%d%d",&u,&v);
109                 update(st[u],en[u],v,1);
110             }
111         }
112     }
113     return 0;
114 }

 

HDU 3974 Assign the task(线段树 时间戳)

标签:set   链接   分配   pre   --   color   eof   names   cto   

原文地址:http://www.cnblogs.com/Leonard-/p/7630085.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!