翻译自:http://codeforces.com/blog/entry/44351
我们先引入这样一个问题:
有一棵树,树上有很多结点,每个结点有一个颜色c,我们现在想知道树上每个结点的子树**(subtree)**,有多少个结点出现颜色c。子树的定义:该结点和其所有的孩子构成的树。

如上图:
- 结点1子树:3个结点出现黄色,2个结点出现红色
- 结点2子树:2个结点出现黄色,1个结点出现红色
- 结点3子树:1个结点出现红色
- 结点4子树:1个结点出现黄色
- 结点5子树:1个结点出现红色
我们现在抛出一个问题;
树上每个结点的子树**(subtree)**,有多少个结点出现颜色黄色
暴力做法
不难想到,我们可以dfs遍历整个树,然后对结点再一次dfs(subtree),计算多少个点出现黄色,代码如下:
int cnt[maxn];
void add(int v, int p, int x){//v结点,p父节点
cnt[ col[v] ] += x;
for(auto u: g[v])
if(u != p)
add(u, v, x)
}
void dfs(int v, int p){
add(v, p, 1);
//现在cnt数组记录
add(v, p, -1);
for(auto u : g[v])
if(u != p)
dfs(u, v);
}
这篇博客翻译自Codeforces的一篇文章,讨论了如何处理树上的动态联通组件问题。文章首先引入了一个问题:在树的每个节点上,求子树中颜色出现的次数。接着,它提出了暴力求解方法,即通过两次深度优先搜索(DFS)来计算每个节点子树中特定颜色的节点数。
729

被折叠的 条评论
为什么被折叠?



