【CF734E】Anton and Tree【树的直径】

文章讲述了如何解决一个关于动态颜色连通块的问题,通过DFS遍历和染色技巧,发现答案是树的直径加1除以2。代码示例展示了如何构建图并使用DFS进行搜索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
在这里插入图片描述

分析

一开始理解错题意了,直接暴力判断连通块个数,我就说怎么这么简单。。。

其实这个颜色的连通块是会动态变化的,染色之后可能会有合并连通块的发生。问题好像瞬间复杂了起来。

但是在染色的时候连通块一定会一起被染色,于是就相当于一个点了,我们也用DFS去缩成一个点,不难发现,新的一棵树上,都是黑白点交替出现的。想到这里可能觉得跟树的深度有关,但是换根深度也会变化。

实际上答案就是(树的直径+1)/2,从直径的中点开始染色就行,只要想到直径方案是显然的。

注意:建新图的时候要判重,不然会多两条边,然后所有子树的搜索次数都会指数增加。要不直接建单向边,然后对面那个连回来。血的教训!!

上代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;

struct node
{
   
   
	int to,next;
}e[400010],e2[400010];

int n,col[200010],dis[200010],dis2[200010];
int k[200010],cnt,vis[200010];
int tot,hd[400010];
int tot2,hd2[400010];

int read() 
{
   
   
    int x=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') 
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值