【POJ】3321 Apple Tree(DFS树的应用)
2015-02-25 17:34
246 查看
题目大意:这边给一棵苹果树,每个节点可以生出多个分支,每个分支可以有0或者1个苹果
现在给出每个节点与分支的情况。以及相应的操作。
思路:
一开始确实是看懵了,想不到为什么是线段树或者是树状数组,这边给的是一棵树,而线段树或者树状数组都是一维数组,所以这边就涉及到一个将树转换成一维数组的方法,便是对树进行dfs。详细看代码吧,初学也不知道怎么表达感悟,等以后加深印象再多写一点内容吧。
线段树做法:比较粗糙,所以在时间上不如树状数组
树状数组做法:
现在给出每个节点与分支的情况。以及相应的操作。
思路:
一开始确实是看懵了,想不到为什么是线段树或者是树状数组,这边给的是一棵树,而线段树或者树状数组都是一维数组,所以这边就涉及到一个将树转换成一维数组的方法,便是对树进行dfs。详细看代码吧,初学也不知道怎么表达感悟,等以后加深印象再多写一点内容吧。
线段树做法:比较粗糙,所以在时间上不如树状数组
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAX 100005 #define ls rt<<1 #define rs ls|1 #define m (r+l)>>1 int col[MAX << 2]; int sum[MAX << 2]; int head[MAX]; int n; int num; int time; struct tree { int v, next; }edg[MAX]; struct f { int s, e; }s[MAX]; /* 这是图中一种建树的方法 */ void addedge(int a, int b) { edg[num].v = b; edg[num].next = head[a]; head[a] = num++; } /* 形象的描述的话,就是给这个节点标记上开始搜索和结束搜索的编号。 一个节点的结束编号恰好是以这个节点为子树的最后一个节点的结束编号。 通过这样就可以明白我们建立的是一个一维数组与树节点的映射关系。 例如 1 2 1 3 对应的便是 1 3 2 而对应的一维数组是 1 2 3 其中1的开始编号是1,结束编号是3。这边结合图形想象一下就可以了。 */ void dfs(int a) { s[a].s = ++time; for (int i = head[a]; i != -1; i = edg[i].next) dfs(edg[i].v); s[a].e = time; } void uprt(int rt) { if (col[rt]) { sum[rt] += col[rt]; col[rs] += col[rt]; col[ls] += col[rt]; col[rt] = 0; } } void uprt2(int rt) { sum[rt] = sum[rs] + sum[ls]; } void build(int l, int r, int rt) { if (l == r) { col[rt] = 0; sum[rt] = 1; return; } int mid = m; build(l, mid, ls); build(mid + 1, r, rs); uprt2(rt); } void updata(int L,int R,int c, int l, int r, int rt) { if (L <= l&&r <= R) { col[rt] = c; uprt(rt); return; } uprt(rt); int mid = m; if (L <= mid) updata(L, R, c, l, mid, ls); if (mid < R) updata(L, R, c, mid + 1, r, rs); uprt2(rt); } int query(int L, int R, int l, int r, int rt) { if (L <= l&&r <= R) return sum[rt]; uprt(rt); int ans = 0; int mid = m; if (L <= mid) ans += query(L, R, l, mid, ls); if (mid < R) ans += query(L, R, mid + 1, r, rs); return ans; } int main() { int n; cin >> n; int a, b; num = 0; time = 0; memset(head, -1, sizeof(head)); for (int i = 0; i < n-1; i++) { scanf("%d%d", &a, &b); addedge(a, b); } dfs(1); build(1, n, 1); int t; cin >> t; cin.get(); char c; while (t--) { scanf("%c%d%*c", &c, &a); if (c == 'C') { b = query(s[a].s, s[a].s, 1, n, 1); if (b == 1) updata(s[a].s, s[a].s, -1, 1, n, 1); else updata(s[a].s, s[a].s, 1, 1, n, 1); } else cout << query(s[a].s, s[a].e, 1, n, 1) << endl; } }
树状数组做法:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAX 100005 int head[MAX]; int num; int time; int sum[MAX]; int n; struct tree { int v, next; }edg[MAX]; struct f { int s, e; }s[MAX]; void addedg(int a, int b) { edg[num].v = b; edg[num].next = head[a]; head[a] = num++; } void dfs(int a) { s[a].s = ++time; for (int i = head[a]; i != -1; i = edg[i].next) dfs(edg[i].v); s[a].e = time; } int lowbit(int k) { return k&(-k); } void add(int s, int k) { while (s <= n) { sum[s] += k; s += lowbit(s); } } int getsum(int s) { int i = 0; while (s > 0) { i += sum[s]; s -= lowbit(s); } return i; } int main() { cin >> n; int a, b; memset(head, -1, sizeof(head)); num = 0; time = 0; for (int i = 0; i < n - 1; i++) { scanf("%d%d", &a, &b); addedg(a, b); } dfs(1); for (int i = 1; i <= n; i++) add(i, 1); char c; int t; scanf("%d%*c", &t); while (t--) { scanf("%c%d%*c", &c, &a); if (c == 'C') { if (getsum(s[a].s) - getsum(s[a].s - 1) == 1) add(s[a].s, -1); else add(s[a].s, 1); } else { cout << getsum(s[a].e) - getsum(s[a].s - 1) << endl;; } } }
相关文章推荐
- POJ 3321 Apple Tree dfs序的应用
- POJ 3321 Apple Tree(dfs+树状数组)
- POJ 3321 Apple Tree (DFS + 树状数组)
- POJ 3321 Apple Tree(DFS + 树状数组)
- [poj 3321]:Apple Tree(树状数组/线段树 和dfs序)
- POJ 3321 - Apple Tree DFS出时间搓,树状数组统计维护..
- POJ 3321 Apple Tree 【树状数组 dfs记录时间戳】
- POJ 3321 Apple Tree(dfs序 + 树状数组)
- POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)
- poj 3321 Apple Tree (dfs+树状数组)
- poj 3321 Apple Tree(dfs + 树状数组)
- 【POJ 3321】 Apple Tree (dfs重标号设区间+树状数组求和)
- POJ 3321 Apple Tree (dfs+线段树)
- POJ 3321 Apple Tree DFS序 + 树状数组
- POJ 3321 Apple Tree(DFS+树状数组)
- POJ 3321 Apple Tree(DFS序 ,修改节点值,子树求和)
- poj - 3321 - Apple Tree(dfs+线段树)
- poj 3321 Apple Tree(dfs标号+树状数组)
- 【POJ 3321】【dfs序(讲解)+(树状数组或者线段树)】Apple Tree【给你一颗树,最初每个节点上都有一个苹果,有两种操作单点修改和查询子树的苹果个数】
- POJ 3321(Apple Tree-dfs序)