hdu3974-Assign the task-(dfs+线段树)

Posted shoulinniao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3974-Assign the task-(dfs+线段树)相关的知识,希望对你有一定的参考价值。

题意:有n个人,有上下级关系,有m个操作,有两种操作1.把一个任务分给某个人,他的下属也会停下手中工作和他一起做;2.查询某个人的当前任务是什么?

解题:n-1个关系,总有一个人没有上级,以他为根节点用dfs搜索整张图可以得到一棵树,按“根左右”先序遍历,根表示自己,遍历到最右边的儿子结束,这段区间为自己的管辖范围,按遍历顺序构造一棵线段树,每个人记录管辖范围,一有任务分给某人,他就分散下去,线段树区间更新。

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<math.h>
  6 #include<string>
  7 #include<map>
  8 #include<queue>
  9 #include<stack>
 10 #include<set>
 11 #define ll long long
 12 #define inf 0x3f3f3f3f
 13 using namespace std;
 14 
 15 int T,n,v,u,cnt,m,x,y;
 16 char s[10];
 17 vector<int>son[50005];///儿子可能有多个,邻接表
 18 int dad[50005];///下标是儿子,内容是父亲
 19 int l[50005];
 20 int r[50005];///l和r两个数组之间的范围 表示 管辖的员工在线段树中的编号范围
 21 int tree[50005*4];
 22 int lazy[50005*4];
 23 
 24 void dfs(int now)///now是当前搜到的员工的编号
 25 
 26     l[now]=++cnt;
 27     for(int i=0;i<son[now].size();i++)
 28     
 29         int xx=son[now][i];
 30         dfs(xx);
 31     
 32     r[now]=cnt;
 33 
 34 
 35 void pushdown(int rt)
 36 
 37     if( lazy[rt]!=-1 )
 38     
 39         tree[ rt*2 ] = tree[ rt*2+1 ] = lazy[ rt*2 ] = lazy[ rt*2+1 ] =lazy[rt];
 40         lazy[rt]=-1;///懒标记赋值给儿子后清空为-1
 41     
 42 
 43 
 44 
 45 void build(int l,int r,int rt)
 46 
 47     if(l==r)
 48     
 49         tree[rt]=-1;
 50         return;
 51     
 52     int mid=(l+r)/2;
 53     build(l,mid,rt*2);
 54     build(mid+1,r,rt*2+1);///不需要求和
 55 
 56 
 57 void update(int L,int R,int p,int l,int r,int rt)
 58 
 59     if( L<=l && r<=R )
 60     
 61         tree[rt]=lazy[rt]=p;
 62         return;
 63     
 64     int mid=(l+r)/2;
 65     pushdown(rt);
 66     if( L<=mid )
 67         update(L,R,p,l,mid,rt*2);
 68     if( mid+1<=R )
 69         update(L,R,p,mid+1,r,rt*2+1);
 70 
 71 
 72 int query(int l,int r,int rt,int x)
 73 
 74     if( l==r )
 75         return tree[rt];
 76     int mid=(l+r)/2;
 77     pushdown(rt);
 78     if(x<=mid)
 79         return query(l,mid,rt*2,x);
 80     else
 81         return query(mid+1,r,rt*2+1,x);
 82 
 83 
 84 int main()
 85 
 86 
 87     scanf("%d",&T);
 88     for(int t=1;t<=T;t++)
 89     
 90         memset(dad,0,sizeof(dad));
 91         memset(lazy,-1,sizeof(lazy));
 92         memset(tree,-1,sizeof(tree));
 93         for(int i=1;i<=n;i++)
 94             son[i].clear();
 95 
 96         scanf("%d",&n);
 97         for(int i=1;i<n;i++)
 98         
 99             scanf("%d%d",&u,&v);///v是u的父亲
100             dad[u]=v;
101             son[v].push_back(u);
102         
103 
104         for(int i=1;i<=n;i++)
105         
106             if( dad[i]==0 )///没有父亲,便是祖宗
107             
108                 v=i;
109                 break;
110             
111         
112         cnt=0;
113         dfs(v);///从祖宗开始往下搜
114 
115         printf("Case #%d:\n",t);
116         scanf("%d",&m);
117         while(m--)
118         
119             string ss;
120             cin>>ss;
121             if( ss[0]==C )///查询a的任务
122             
123                 scanf("%d",&x);
124                 int ans=query(1,cnt,1,l[x]);
125                     printf("%d\n",ans);
126             
127             else
128             
129                 scanf("%d%d",&x,&y);///让员工a做任务b,a会叫他的下属一起做,左右区间表示需要做的人,包括自己
130                 update( l[x],r[x],y,1,cnt,1 );
131             
132         
133 
134     
135     return 0;
136 

 

以上是关于hdu3974-Assign the task-(dfs+线段树)的主要内容,如果未能解决你的问题,请参考以下文章

HDU3974 Assign the task

HDU 3974 Assign the task

hdu 3974 Assign the task(线段树)

hdu 3974 Assign the task 线段树 DFS序

HDU - 3974 Assign the task (线段树区间修改+构建模型)

hdu3974-Assign the task-(dfs+线段树)