【LibreOJ #3014. 「JOI 2019 Final」独特的城市】【长链剖分】

博客介绍了如何解决一道图论问题,即在一棵树中找到每个节点支配的颜色种类数。首先求出树的直径,然后通过长链剖分策略,以直径两端点为根进行深度优先搜索。在DFS过程中,使用栈存储路径上的关键节点,并在遍历节点时更新答案。整体算法的时间复杂度为O(n)。
摘要由CSDN通过智能技术生成

题意

有一棵 n n n个点的数,每个点有一种颜色。定义 y y y x x x支配当且仅当不存在 z z z满足 d i s ( x , z ) = d i s ( x , y ) dis(x,z)=dis(x,y) dis(x,z)=dis(x,y)。对于每个点,求出所有被他支配的点中有多少种不同的颜色。
n ≤ 300000 n\le300000 n300000

分析

先把直径求出来,对于一个点,被他支配的点一定在他到直径两端点中离他较远的那个点的路径上。
设直径两端点为 s s s t t t,以 s s s t t t分别为根做一次。
先把树长链剖分,然后在dfs时用一个栈记录该点到根路径上可能作为答案的点。
处理到一个点时,先把栈中和他距离不大于深度最大的轻儿子的点退栈,然后递归重儿子;接着把栈中和他距离不大于重儿子的点退栈,然后处理该点的答案并递归所有轻儿子。
注意每次递归儿子前都要先把该点入栈,用一个全局的桶维护答案即可。
时间复杂度 O ( n ) O(n) O

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值