codeforces 734E(DFS,树的直径(最长路))

时间:2023-03-08 21:24:41

题目链接:http://codeforces.com/contest/734/problem/E

题意:有一棵黑白树,每次操作可以使一个同色连通块变色,问最少几次操作能使树变成全黑或全白。

思路:先进行缩点,同色连通块当作一点,用dfs实现并得到新图。答案即为(最长直径+1)/2。

关于最长直径的求法:http://www.cnblogs.com/*qi/archive/2012/04/08/2437424.html

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + ;
int col[N],refl[N],maxdis,maxpos;
vector <int> G[N],E[N];
bool vis[N];
void dfs(int x,int cur)
{
if(vis[x])
return;
vis[x] = ;
if(col[x] != col[cur])
{
E[x].push_back(cur);
E[cur].push_back(x);
cur = x;
}
for(int i = ; i < G[x].size(); i++)
dfs(G[x][i],cur);
}
void DFS(int x,int dis)
{
if(vis[x])
return;
vis[x] = ;
if(dis > maxdis)
{
maxdis = dis;
maxpos = x;
}
for(int i = ; i < E[x].size(); i++)
DFS(E[x][i],dis + );
}
int main()
{
int n;
scanf("%d",&n);
for(int i = ; i <= n; i++)
scanf("%d",col + i);
for(int i = ; i <= n - ; i++)
{
int u,v;
scanf("%d %d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(,);
memset(vis,,sizeof(vis));
DFS(,);
memset(vis,,sizeof(vis));
DFS(maxpos,);
printf("%d\n",(maxdis + ) >> );
return ;
}