码迷,mamicode.com
首页 > 移动开发 > 详细

POJ 3321 Apple Tree

时间:2015-01-21 13:24:57      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

参考来源:http://www.cnblogs.com/frog112111/p/3269281.html

 

/*
*POJ 3321 树状数组 + DFS
*题意:一棵苹果树,有n个节点,每个节点上有或仅有1个苹果,初始时每个节点上都有苹果
*   给出n-1个节点间关系
*   m次操作:
*       C  x 若x节点有苹果,则摘下,若没有,则会长出一个
*       Q  x 询问x节点以下的所有节点的苹果数之和
*/
/*DFS求每个节点的第一次访问时间和最后的访问时间,
*则begin[x] 和 end[x] 之间的节点就是x的子树
*剩下的就是用树状数组求 getSum(end[u]) - getSum(begin[u] - 1)
*/
#include <cstdio>

#define lowbit(x) x&(-x)
#define MAXN 100010
int c[MAXN], n;
int first[MAXN]; //记录邻接表的头节点的编号
int begin[MAXN]; //每个节点的起始时间
int end[MAXN];  //每个节点的结束时间
bool has[MAXN]; //记录节点上是否有苹果
int count;
void update(int x, int val)
{
	for (int i = x; i <= n; i += lowbit(i)) {
		c[i] += val;
	}
}

int getSum(int x)
{
	int sum = 0;
	for (int i = x; i > 0; i -= lowbit(i)) {
		sum += c[i];
	}
	return sum;
}

struct edge {
	int v, next;
} edge[MAXN]; //记录边的信息

void insert(int u, int v)
{
	edge[count].v = v;
	edge[count].next = first[u];
	first[u] = count++;
}
void dfs(int x)
{
	begin[x] = ++ count;
	for (int i = first[x]; i != -1; i = edge[i].next) {
		dfs(edge[i].v);
	}
	end[x] = count;
}

int main()
{
	int u, v, m, ans;
	char s[10];
	scanf("%d", &n);
	count = 0;
	for (int i = 0; i <= MAXN; i++) {
		first[i] = -1;
	}
	for (int i = 0; i < n - 1; i ++) {
		scanf("%d %d", &u, &v);
		insert(u, v);
	}
	count = 0;
	dfs(1);

	// for(int i = 0; i < n; i++){
	//  printf("%d  %d  %d  %d  %d\n",first[i], begin[i], end[i], edge[i].v, edge[i].next);
	// }

	for (int i = 1; i <= n; i++) {
		update(i, 1);
		has[i] = true;
	}
	scanf("%d", &m);
	while (m--) {
		scanf("%s %d", s, &u);
		if (s[0] == ‘Q‘) {
			printf("%d\n", getSum(end[u]) - getSum(begin[u] - 1));
		} else {
			if (has[u]) {
				update(begin[u], -1);
			} else {
				update(begin[u], 1);
			}
			has[u] = !has[u];
		}
	}
	return 0;
}

  

POJ 3321 Apple Tree

标签:

原文地址:http://www.cnblogs.com/subrshk/p/4238543.html

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