【图论】CF1467E - Distinctive Roots in a Tree
作者:互联网
题目链接:https://codeforces.com/contest/1467/problem/E
算法流程
-
以1号节点为根,先序遍历这棵树,记录以下信息:
a. 每一种权值出现的次数 \(cnt[i]\)
b. 每一种权值出现的深度 \(dep[i]\)
c. 每一种权值出现的最大深度 \(mdp[i]\) -
以1号节点为根,再次先序遍历这棵树,记录以下信息:
a. 假如这种权值出现的次数 \(cnt[i]=1\) ,那么直接忽略这种权值,结束。
b. 假如这种权值的最大深度 \(mdp[i]=1\) ,那么给这种权值的所有点都打上 \(down\) 标记,结束。
c. 那么这种权值的最大深度 \(mdp[i]\geq2\),那么给这种权值的所有点都打上 \(down\) 标记,给这种权值的所有 \(dep[i]\geq2\) 的点的前一个点打上 \(方向up\) 标记,结束。 -
把 \(方向up\) 标记的值,恰好等于 \(cnt[i]-1\) 的 \(down\) 标记清除。
-
下推所有down标记,上推所有的up标记,统计答案。
算法解释
总结
其中,要计算“带有方向的up标记”的方向,目前没有想到更好的办法,使用的是类似倍增lca的倍增算法计算出方向。总体时间复杂度 \(O(nlogn)\) 。
一道对我来说非常难的“树”论问题,也通过这一题感觉到自己确实比起9个月前强大了,无论是从代码能力、逻辑分析能力、或者是恒心和耐心都是。
标签:cnt,标记,Distinctive,Tree,up,down,权值,mdp,CF1467E 来源: https://www.cnblogs.com/purinliang/p/14257293.html