dfs序题目练习
参考博文:http://blog.csdn.net/qwe2434127/article/details/49819975
http://blog.csdn.net/qq_24489717/article/details/50569644
dfs序比较重要的性质:一棵子树的所有节点在dfs序里是连续一段,主要就是利用这个性质来解题.
作为预处理,首先将将树的所有节点按深度保存起来,每个深度的所有节点用一个线性结构保存,每个深度的节点相对顺序要和前序遍历一致。
然后从树的根节点进行dfs,对于每个节点记录两个信息,一个是dfs进入该节点的时间戳in[id],另一个是dfs离开该节点的时间戳out[id]。
最后对于每次查询,求节点v在深度h的所有子节点,只需将深度为h并且dfs进入时间戳在in[v]和out[v]之间的所有节点都求出来即可,由于对于 每个深度的所有节点,相对顺序和前序遍历的顺序以致,那么他们的dfs进入时间戳也是递增的,于是可以通过二分搜索求解。
Poj 3321:
题型一:对某个点X权值加上一个数W,查询某个子树X里所有点权值和。
解:列出dfs序,实现修改一个数,查询一段序列的和,显然这个序列可以用树状数组维护。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long LL;
const int N = ;
struct Edge{
int v,next;
}edge[N];
int head[N],tot,c[N];
int in[N],out[N];
bool have[N];
int cnt;
void init(){
tot = ;
cnt = ;
memset(head,-,sizeof(head));
memset(c,,sizeof(c));
}
void addEdge(int u,int v,int &k){
edge[k].v = v,edge[k].next = head[u],head[u] = k++;
}
void dfs(int u){
in[u] = ++cnt;
for(int k=head[u];k!=-;k=edge[k].next){
dfs(edge[k].v);
}
out[u] = cnt;
}
int lowbit(int x){
return x&(-x);
}
int getsum(int id){
int sum = ;
for(int i=id;i>=;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void update(int id,int x){
for(int i=id;i<=cnt;i+=lowbit(i)){
c[i]+=x;
}
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF){
init();
for(int i=;i<n-;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v,tot);
}
dfs();
/*for(int i=1;i<=n;i++){
printf("%d %d\n",in[i],out[i]);
}*/
for(int i=;i<=n;i++){
have[i] = ;
update(in[i],);
}
int q;
scanf("%d",&q);
while(q--){
char s[];
int x;
scanf("%s%d",s,&x);
if(s[]=='Q'){
printf("%d\n",getsum(out[x])-getsum(in[x]-));
}else{
if(have[x]) update(in[x],-);
else update(in[x],);
have[x] = !have[x];
}
}
}
return ;
}
hdu 3886 :
统计某一个结点下面比编号比其小的结点数目.
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long LL;
const int N = ;
struct Edge{
int v,next;
}edge[N];
int head[N],tot,c[N];
int in[N],out[N];
bool have[N];
int cnt;
void init(){
tot = ;
cnt = ;
memset(head,-,sizeof(head));
memset(c,,sizeof(c));
}
void addEdge(int u,int v,int &k){
edge[k].v = v,edge[k].next = head[u],head[u] = k++;
}
void dfs(int u,int fa){
in[u] = ++cnt;
for(int k=head[u];k!=-;k=edge[k].next){
if(edge[k].v == fa) continue;
dfs(edge[k].v,u);
}
out[u] = cnt;
}
int lowbit(int x){
return x&(-x);
}
int getsum(int id){
int sum = ;
for(int i=id;i>=;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void update(int id,int x){
for(int i=id;i<=cnt;i+=lowbit(i)){
c[i]+=x;
}
}
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=EOF,n+q){
init();
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v,tot);
addEdge(v,u,tot);
}
dfs(q,-);
bool flag = true;
for(int i=;i<=n;i++){
if(!flag) printf(" ");
printf("%d",getsum(out[i])-getsum(in[i]-));
flag = false;
update(in[i],);
}
printf("\n");
}
return ;
}
hdu 5692:利用DFS序将树形结构转换成为线段树.便于维护和查找.
http://www.cnblogs.com/liyinggang/p/5925196.html
hdu 5468:DFS序+容斥原理 ,求解每个结点下面与其互质的结点的个数。
http://www.cnblogs.com/liyinggang/p/5926105.html
bzoj 2819:DFS序+博弈+树状数组+lca,维护树上的一条路上的异或值.
http://www.cnblogs.com/liyinggang/p/5927232.html
update中...
dfs序题目练习的更多相关文章
- DFS序的题目列表
所谓dfs序就是将之前的顺序进行修改,获得一个新的序列,然后再新的序列下进行一系列其他的操作 一般题目给你的都会是一棵树,然后点之间都是无关的,我们首要的任务就是先把这些序列重新排.然后再根据dfs的 ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- DFS序+线段树 hihoCoder 1381 Little Y's Tree(树的连通块的直径和)
题目链接 #1381 : Little Y's Tree 时间限制:24000ms 单点时限:4000ms 内存限制:512MB 描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每 ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- DFS序+线段树+bitset CF 620E New Year Tree(圣诞树)
题目链接 题意: 一棵以1为根的树,树上每个节点有颜色标记(<=60),有两种操作: 1. 可以把某个节点的子树的节点(包括本身)都改成某种颜色 2. 查询某个节点的子树上(包括本身)有多少个不 ...
- dfs序
dfs序比较重要的性质:一棵子树的所有节点在dfs序里是连续一段,主要就是利用这个性质来解题 题型一:对某个点X权值加上一个数W,查询某个子树X里所有点权值和. 解:列出dfs序,实现修改一个数,查询 ...
- [BZOJ 2819]NIM(dfs序维护树上xor值)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2819 分析: 树上的nim游戏,关键就是要判断树上的一条链的异或值是否为0 这个题目有 ...
- 【BZOJ-3252】攻略 DFS序 + 线段树 + 贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 339 Solved: 130[Submit][Status][Discuss] D ...
随机推荐
- OpenFlow 消息
消息类型 OpenFlow 的消息共分为三类: Controller-to-Switch 顾名思义,此类消息是由控制器主动发出 Features 用于获取交换机特性 Configuration 用于配 ...
- BZOJ3724 [HNOI2012]集合选数 【状压dp】
题目链接 BZOJ3724 题解 构造矩阵的思路真的没想到 选\(x\)就不能选\(2x\)和\(3x\),会发现实际可以转化为矩阵相邻两项 \[\begin{matrix}1 & 3 &am ...
- 第一个python程序(2)
输入和输出 输出 用print加上字符串,就可以向屏幕上输出指定的文字.比如输出'hello, world',用代码实现如下: >>> print 'hello, world' pr ...
- Codeforces 931.F Teodor is not a liar!
F. Teodor is not a liar! time limit per test 1 second memory limit per test 256 megabytes input stan ...
- libevent学习文档(三)working with event
Events have similar lifecycles. Once you call a Libevent function to set up an event and associate i ...
- 我是大SB
哈哈哈 我就是个大SB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- openstack配置模块
一.简介 openstack中负责处理配置的模块是oslo.config,它可以处理配置项和配置文件.通常的配置处理都是如下形式: from oslo.config import cfg CONF=c ...
- [DeeplearningAI笔记]序列模型1.3-1.4循环神经网络原理与反向传播公式
5.1循环序列模型 觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.3循环神经网络模型 为什么不使用标准的神经网络 假如将九个单词组成的序列作为输入,通过普通的神经网网络输出输出序列, 在 ...
- Linux下打包压缩war和解压war包 zip和jar
============jar================= 把当前目录下的所有文件打包成game.warjar -cvfM0 game.war ./ -c 创建war包-v 显示过程信息 ...
- struts2验证规则validation配置文件命名方式总结
1.Action级别校验命名格式: ActionClassName-validation.xml 2.Action中某个方法的校验命名格式: ActionClassName-ActionAliasNa ...