题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1811

给你一棵树,每个节点有一个颜色。问删除一条边形成两棵子树,两棵子树有多少种颜色是有相同的。

启发式合并,小的合并到大的中。类似的题目有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 + ;
struct Edge {
int next, to, index;
}edge[N << ];
int color[N], head[N], tot;
int sum[N], ans[N], res[N]; //sum[color]:颜色color节点个数, ans[u]表示u点及字节点的答案, res[edge]表示边的答案
map <int, int> cnt[N]; //cnt[u][color] 表示u点子树color颜色有多少个节点 void init(int n) {
for(int i = ; i <= n; ++i) {
head[i] = -;
sum[i] = ;
cnt[i].clear();
}
tot = ;
} 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]] = ;
ans[u] = cnt[u][color[u]] < sum[color[u]] ? : ;
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 == && 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 = ; i <= n; ++i) {
scanf("%d", color + i);
++sum[color[i]];
}
for(int i = ; i < n; ++i) {
scanf("%d %d", &u, &v);
add_edge(u, v, i);
add_edge(v, u, i);
}
dfs(, -, );
for(int i = ; i < n; ++i) {
printf("%d\n", res[i]);
}
}
return ;
}

csu oj 1811: Tree Intersection (启发式合并)的更多相关文章

  1. CSU 1811: Tree Intersection(线段树启发式合并||map启发式合并)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1811 题意:给出一棵树,每一个结点有一个颜色,然后依次删除树边,问每次删除树边之后,分开的两个 ...

  2. dsu on tree 树上启发式合并 学习笔记

    近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...

  3. dsu on tree[树上启发式合并学习笔记]

    dsu on tree 本质上是一个 启发式合并 复杂度 \(O(n\log n)\) 不支持修改 只能支持子树统计 不能支持链上统计- 先跑一遍树剖的dfs1 搞出来轻重儿子- 求每个节点的子树上有 ...

  4. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  5. AGC 014E.Blue and Red Tree(思路 启发式合并)

    题目链接 \(Description\) 给定两棵\(n\)个点的树,分别是由\(n-1\)条蓝边和\(n-1\)条红边组成的树.求\(n-1\)次操作后,能否把蓝树变成红树. 每次操作是,选择当前树 ...

  6. 【树状数组】CSU 1811 Tree Intersection (2016湖南省第十二届大学生计算机程序设计竞赛)

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1811 题目大意: 一棵树,N(2<=N<=105)个节点,每个节点有一种颜 ...

  7. CSU 1811 Tree Intersection

    莫队算法,$dfs$序. 题目要求计算将每一条边删除之后分成的两棵树的颜色的交集中元素个数. 例如删除$u->v$,我们只需知道以$v$为$root$的子树中有多少种不同的颜色(记为$qq$), ...

  8. dsu on tree(树上启发式合并)

    简介 对于一颗静态树,O(nlogn)时间内处理子树的统计问题.是一种优雅的暴力. 算法思想 很显然,朴素做法下,对于每颗子树对其进行统计的时间复杂度是平方级别的.考虑对树进行一个重链剖分.虽然都基于 ...

  9. 启发式合并CSU - 1811

    F - Tree Intersection CSU - 1811 Bobo has a tree with n vertices numbered by 1,2,…,n and (n-1) edges ...

随机推荐

  1. HDU 2144 (最长连续公共子列 + 并查集) Evolution

    我发现我一直理解错题意了,这里的子序列指的是连续子序列,怪不得我写的LCS一直WA 顺便复习一下并查集 //#define LOCAL #include <iostream> #inclu ...

  2. VS启用IIS调试的方法及可能碰到的问题。

    经常有这种情况, 开发机本地正常, 但是一旦发布到服务上后, 就出现各种问题. 这是由于开发机和服务器环境不一样造成的, 所以开发时要尽可能的模拟真实性.  这时候, VS的这个功能就帮大忙了. 如何 ...

  3. Android 系统属性

    /************************************************************************ * Android 系统属性 * 说明: * 由于需 ...

  4. hihoCoder #1182 欧拉路·三 (变形)

    题意: 写出一个环,环上有2^n个格子,每个格子中的数字是0或1,相连着的n个格子可以组成一个数的二进制,要求给出这2^n个数字的序列,使得组成的2^n个数字全是不同的.(即从0到2^n-1) 思路: ...

  5. UIColor,CGColor,CIColor三者的区别和联系

    UIColor,CGColor,CIColor三者的区别和联系((转)) 最近看了看CoreGraphics的东西,看到关于CGColor的东西,于是就想着顺便看看UIColor,CIColor,弄清 ...

  6. Java循环语句之 for

    Java 的循环结构中除了 while 和 do...while 外,还有 for 循环,三种循环可以相互替换. 语法: 执行过程: <1>. 执行循环变量初始化部分,设置循环的初始状态, ...

  7. String定义与方法

    //5种构造方法 public void Con(){ String str = "sfaj"; String str1 = new String("sfajdf&quo ...

  8. JS判断手机访问页面,根据手机访问或者PC访问跳转

    当用户访问你网站时,如果是PC端访问,则不作处理,如果是手机或者平板访问,就跳转到自己定义的手机页面去,这个在做webapp的时候经常用到,把代码分享给大家,希望对大家有所帮助. 首先,你要在页面中引 ...

  9. Golang 绘图基础 -绘制简单图形

    前一节讲的是 绘图到不同输出源,请看地址: http://www.cnblogs.com/ghj1976/p/3440856.html 上一节的例子效果是通过设置每一个点的的RGBA属性来实现的,这是 ...

  10. JavaScript对象(document对象 图片轮播)

    图片轮播: 需要注意的HTML需要img标签,他和input标签一样,是非封闭的标签 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...