csu oj 1811: Tree Intersection (启发式合并)
2016-09-14 15:03
399 查看
题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1811
给你一棵树,每个节点有一个颜色。问删除一条边形成两棵子树,两棵子树有多少种颜色是有相同的。
启发式合并,小的合并到大的中。类似的题目有http://codeforces.com/contest/600/problem/E
给你一棵树,每个节点有一个颜色。问删除一条边形成两棵子树,两棵子树有多少种颜色是有相同的。
启发式合并,小的合并到大的中。类似的题目有http://codeforces.com/contest/600/problem/E
//#pragma comment(linker, "/STACK:102400000, 102400000") #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <vector> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> using namespace std; typedef long long LL; typedef pair <int, int> P; const int N = 1e5 + 5; struct Edge { int next, to, index; }edge[N << 1]; int color , head , tot; int sum , ans , res ; //sum[color]:颜色color节点个数, ans[u]表示u点及字节点的答案, res[edge]表示边的答案 map <int, int> cnt ; //cnt[u][color] 表示u点子树color颜色有多少个节点 void init(int n) { for(int i = 1; i <= n; ++i) { head[i] = -1; sum[i] = 0; cnt[i].clear(); } tot = 0; } inline void add_edge(int u, int v, int id) { edge[tot].next = head[u]; edge[tot].to = v; edge[tot].index = id; head[u] = tot++; } void dfs(int u, int pre, int id) { cnt[u][color[u]] = 1; ans[u] = cnt[u][color[u]] < sum[color[u]] ? 1 : 0; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(v == pre) continue; dfs(v, u, edge[i].index); if(cnt[u].size() < cnt[v].size()) { swap(cnt[u], cnt[v]); swap(ans[u], ans[v]); } for(auto it : cnt[v]) { int &num = cnt[u][it.first]; if(num == 0 && num + it.second < sum[it.first]) { ++ans[u]; } else if(num + it.second == sum[it.first] && num) { //说明此子树的it.first颜色节点个数已满 --ans[u]; } num += it.second; } } res[id] = ans[u]; } int main() { int n, u, v; while(scanf("%d", &n) != EOF) { init(n); for(int i = 1; i <= n; ++i) { scanf("%d", color + i); ++sum[color[i]]; } for(int i = 1; i < n; ++i) { scanf("%d %d", &u, &v); add_edge(u, v, i); add_edge(v, u, i); } dfs(1, -1, 0); for(int i = 1; i < n; ++i) { printf("%d\n", res[i]); } } return 0; }
相关文章推荐
- CSU 1811 Tree Intersection(启发式合并)
- CSU 1811 Tree Intersection(Treap启发式合并)
- CSU 1811 Tree Intersection(启发式合并)
- [CSU - 1811 (湖南省赛16)] Tree Intersection (启发式合并)
- CSU 1811 Tree Intersection(线段树+启发式合并 解法)
- SPOJ:Free tour II (树分治+启发式合并)
- POJ 1611 The Suspects 并查集(代码带启发式合并)
- 【楼天城男人八题】【树分治|Treap+启发式合并】POJ1741 Tree
- bzoj 2733 splay+启发式合并
- bzoj 1438(启发式合并)
- hdu 6133---Army Formations(启发式合并+树状数组)
- 51nod 1907(多项式乘法启发式合并)
- [HNOI2009]梦幻布丁 启发式链表合并
- BOZJ2733 [HNOI2012]永无乡(Treap+启发式合并)
- BZOJ 2733: [HNOI2012]永无乡(线段树启发式合并)
- HDU - 4424 Conquer a New Region 思维+并查集启发式合并
- [BZOJ3545][ONTAK2010]Peaks(splay启发式合并)
- [hdu 6191 Query on A Tree] 字典树启发式合并
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
- bzoj2733 [HNOI2012]永无乡(splay启发式合并)