HDU-3974 Assign the task(多叉树DFS时间戳建线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=3974
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
The company usually assigns some tasks to some employees to finish.When a task is assigned to someone,He/She will assigned it to all his/her subordinates.In other words,the person and all his/her subordinates received a task in the same time. Furthermore,whenever a employee received a task,he/she will stop the current task(if he/she has) and start the new one.
Write a program that will help in figuring out some employee’s current task after the company assign some tasks to some employee.
Input
For each test case:
The first line contains an integer N (N ≤ 50,000) , which is the number of the employees.
The following N - 1 lines each contain two integers u and v, which means the employee v is the immediate boss of employee u(1<=u,v<=N).
The next line contains an integer M (M ≤ 50,000).
The following M lines each contain a message which is either
"C x" which means an inquiry for the current task of employee x
or
"T x y"which means the company assign task y to employee x.
(1<=x<=N,0<=y<=10^9)
Output
Sample Input
C
T
C
T
C
Sample Output
Case #:
-
题意:
公司中有N个职员,只有一个老板,其余每个职员对应一个上司,这N个职员刚好组成一棵树。然后有M个操作。
当给一个职员x分配任务y时(即 T x y),x及其下属及其下属的下属都会放下手头的工作去完成任务y。对于每次询问(即C x),程序输出职员x正在进行什么任务。
简而言之:给出一个有向多叉树,初始所有节点为-1.有两种操作,一种为(T,x,y),表示将x节点及其的所有子树中的节点变为y,另一种为(C,x),为求x节点的值。
题解:
这道题的难点就在于如何将题中的对应关系转化为线段树的模型,在于如何处理好多叉树和线段树间的映射关系。
线段树的本质就是对一整段连续区间进行操作。所以这道题的关键就在于清楚怎么将对多叉树的操作转化成对一整段连续区间的操作。
很明显该公司的所有员工间的关系可以用一颗多叉树来表示。然后从公司老板(也就是入度为0的点)出发,用dfs给这棵树打上时间戳,确定每个点的影响范围并记录下来。
根据新分配的id号码将其节点对应映射到线段树上面。这样分配任务就相当于更新一段连续的节点,查询任务相当于单点查询。
代码如下:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <math.h>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
//const double PI=acos(-1);
const int maxn=1e5+;
using namespace std;
//ios::sync_with_stdio(false);
// cin.tie(NULL); struct Edge_node
{
int v;
int next;
}Edge[*]; struct SegTree_node
{
int l;
int r;
int num;
}SegTree[<<];
int n,m;
int cnt;//边的计数器,从0开始
int num;//线段树序号的计数器,从1开始
int head[];
int vis[];//是否有上司,即入度为0
int st[];//开始遍历时的编号,同时作为线段树中的序号
int ed[];//遍历结束后的序号,表示该点在线段树中可以影响的最后一个序号(即上司) void init()//初始化
{
cnt=;
num=;
memset(head,-,sizeof(head));
memset(st,,sizeof(st));
memset(ed,,sizeof(ed));
memset(Edge,,sizeof(Edge));
memset(vis,,sizeof(vis));
} void add_edge(int u,int v)
{
Edge[cnt].v=v;
Edge[cnt].next=head[u];
head[u]=cnt++;
} void DFS(int u)
{
num++;
st[u]=num;
for(int i=head[u];i!=-;i=Edge[i].next)
{
DFS(Edge[i].v);
}
ed[u]=num;
} void PushDown(int rt)
{
if(SegTree[rt].num!=-)
{
SegTree[rt<<].num=SegTree[rt<<|].num=SegTree[rt].num;
SegTree[rt].num=-;
}
} void Build(int l,int r,int rt)
{
SegTree[rt].l=l;
SegTree[rt].r=r;
SegTree[rt].num=-;
if(l==r)
return ;
int mid=(l+r)>>;
Build(l,mid,rt<<);
Build(mid+,r,rt<<|);
} void Update(int L,int R,int C,int rt)
{
int l=SegTree[rt].l;
int r=SegTree[rt].r;
if(L<=l&&R>=r)
{
SegTree[rt].num=C;
return ;
}
PushDown(rt);
int mid=(l+r)>>;
if(L<=mid)
Update(L,R,C,rt<<);
if(R>mid)
Update(L,R,C,rt<<|);
} int Query(int L,int rt)
{
int l=SegTree[rt].l;
int r=SegTree[rt].r;
if(l==r)
return SegTree[rt].num;
PushDown(rt);
int mid=(l+r)>>;
if(L<=mid)
Query(L,rt<<);
else if(L>mid)
Query(L,rt<<|);
} int main()
{
int T;
scanf("%d",&T);
for(int k=;k<=T;k++)
{
printf("Case #%d:\n",k);
init();
scanf("%d",&n);
for(int i=;i<n;i++)
{
int u,v;
scanf("%d %d",&u,&v);
vis[u]=;
add_edge(v,u);
}
for(int i=;i<=n;i++)
{
if(!vis[i])
{
DFS(i);
break;
}
}
Build(,num,);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
char c[];
int x;
scanf("%s %d",c,&x);
if(c[]=='C')
{
printf("%d\n",Query(st[x],));
}
else if(c[]=='T')
{
int t;
scanf("%d",&t);
//st[x]->ed[x]代表x及x的下属在线段树中的区间范围
Update(st[x],ed[x],t,);
}
}
}
return ;
}
HDU-3974 Assign the task(多叉树DFS时间戳建线段树)的更多相关文章
- HDU 3974 Assign the task 暴力/线段树
题目链接: 题目 Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 3974 Assign the task (DFS序 + 线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操 ...
- HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)
描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...
- hdu 3974 Assign the task(dfs序上线段树)
Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...
- HDU 3974 Assign the task(DFS序)题解
题意:给出一棵树,改变树的一个节点的值,那么该节点及所有子节点都变为这个值.给出m个询问. 思路:DFS序,将树改为线性结构,用线段树维护.start[ ]记录每个节点的编号,End[ ]为该节点的最 ...
- HDU 3974 Assign the task (DFS+线段树)
题意:给定一棵树的公司职员管理图,有两种操作, 第一种是 T x y,把 x 及员工都变成 y, 第二种是 C x 询问 x 当前的数. 析:先把该树用dfs遍历,形成一个序列,然后再用线段树进行维护 ...
- HDU - 3974 Assign the task (DFS建树+区间覆盖+单点查询)
题意:一共有n名员工, n-1条关系, 每次给一个人分配任务的时候,(如果他有)给他的所有下属也分配这个任务, 下属的下属也算自己的下属, 每次查询的时候都输出这个人最新的任务(如果他有), 没有就输 ...
- HDU 3974 Assign the task 并查集/图论/线段树
Assign the task Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- HDU 3974 Assign the task(简单线段树)
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- tensorflow中的神经网络笔记
1.NN----神经网络 2.CNN卷积神经网络 CNN网络一共有5个层级结构: 输入层 卷积层 激活层 池化层 全连接FC层 一.输入层 与传统神经网络/机器学习一样,模型需要输入的进行预处理操作, ...
- 用Python在00:00给微信好友发元旦祝福语
2019年的元旦即将来临,这里用Python撸一串简单的代码来实现定点给微信里的所有小伙伴发祝福语 环境说明 Python版本: 不限 第三方库: itchat, schedule 注:所有祝福语来源 ...
- POJ 1519:Digital Roots
Digital Roots Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 25766 Accepted: 8621 De ...
- Eclipse中常用的快捷键总结!不收藏后悔!
Eclipse中常用的快捷键总结!不收藏后悔!Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ ...
- 吴裕雄--天生自然C++语言学习笔记:C++简介
C++ 是一种中级语言,它是由 Bjarne Stroustrup 于 年在贝尔实验室开始设计开发的.C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言.C++ 可运行于多种平台上,如 ...
- 汪慧和201771010123《面向对象程序设计JAVA》第四周实验总结
第一部分:理论知识学习部分 1.类 类(class)是具有相同属性和行为的一组对象的集合,是构造程序的基本单元,是构造对象的模板或蓝图. 2.对象 对象:即数据,对象有三个特性——1.行为 2.状态 ...
- Hough直线and圆环变换(如何检测直线、圆环)
1.霍夫变换 2.cv2.HoughLines() 返回值就是(ρ, θ).ρ 的单位是像素,θ 的单位是弧度.这个函数的第一个参 数是一个二值化图像,所以在进行霍夫变换之前要首先进行二值化,或者进行 ...
- JavaScript学习总结(五)
之前的几讲中我们曾经说过,JavaScript中是没有类的概念的.但是我们讲过对象,那么这个对象是怎么来的呢? 只要有函数即可创建对象 自定义对象 自定义对象的方式: 1. 使用无参的函数创建对象 & ...
- CentOS7下MySQL8的二进制基本安装配置
前言 基于本地Centos7.6虚拟机Mysql8的配置(亲测有效) 一.安装前的准备 1.到官网下载mysql-8.0.16-linux-glibc2.12-x86_64.tar.xz 2.通过Xs ...
- 201403-2 窗口 Java
要想到定义一个窗口类,判断点在不在矩形里好判断 需要一个数组,存放结果 import java.util.ArrayList; import java.util.List; import java.u ...