分析
一开始理解错题意了,直接暴力判断连通块个数,我就说怎么这么简单。。。
其实这个颜色的连通块是会动态变化的,染色之后可能会有合并连通块的发生。问题好像瞬间复杂了起来。
但是在染色的时候连通块一定会一起被染色,于是就相当于一个点了,我们也用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')