题意:给出一棵有n个结点的树,对于每一个结点,如果任意删除一条边后再任意添加一条边能使这个结点成为这棵树的重心,则输出1;反之输出0。
解:重心的特点:以重心为根节点时,其最大子树的节点数最小,且每个子树大小不超过n/2。考虑更换一条边的操作,如果这个结点当根节点时,有一棵子树大小超过n/2,那么砍掉这颗子树不超过n/2的最大子树,并把它接到根节点来。如果此时最大子树仍超过n/2,那么这个结点不可能成为重心。
对于每一个结点都O(n)地判断一遍显然是会超时的,考虑类似于换根的操作。先以随便一个结点作为根,dfs出每个结点的子树大小。然后再dfs一遍,进入一个结点时,其父结点和之前的结点为当前结点的子树。递归进入的时候记录之前小于等于n/2的最大子树和次大子树(当进入的结点在最大子树中时,应该传次大子树的值)。然后比较判断。
cf官方题解的做法更简洁。一开始以树的重心为根进行dfs,这样只要考虑之前结点形成的子树。已知当前子树外其他结点加起来大于等于n/2,因此又只要考虑原来第一和第二大的子树。这样事情就很简单了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?