思路:缩点,求树的直径d,(d+1)/2就是答案,即从最长链的中间开始变色。
# include <bits/stdc++.h>
# define pb push_back
using namespace std;
const int maxn = 2e5+30;
vector<int>v[maxn], s[maxn];
int ans=0, a[maxn], cnt=0, vis[maxn], h[maxn], fa[maxn];
void dfs(int cur, int tag)
{
vis[cur] = 1;
fa[cur] = tag;
for(auto to : v[cur])
{
if(vis[to] || a[to] != a[cur] ) continue;
vis[to] = 1;
dfs(to, tag);
}
}
void dfs2(int cur, int pre)
{
int mx=0, mmx=0;
for(auto to : s[cur])
{
if(to == pre) continue;
dfs2(to, cur);
mx = max(mx, h[to]+1);
if(mx > mmx) swap(mx, mmx);//维护两个最深的儿子。
}
h[cur] = mmx;
ans = max(ans, mx+mmx);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; ++i) scanf("%d",&a[i]);
for(int i=1; i<n; ++i)
{
int a, b;
scanf("%d%d",&a,&b);
v[a].pb(b), v[b].pb(a);
}
for(int i=1; i<=n; ++i)
if(!vis[i])
dfs(i, ++cnt);
for(int i=1; i<=n; ++i)
for(auto j : v[i])
if(a[j] != a[i]) s[fa[i]].pb(fa[j]);
dfs2(1, 0);
printf("%d\n",(ans+1)/2);
return 0;
}