Codeforces E-Anton and Tree

E. Anton and Tree

题目大意:给你一棵树, 每个节点被涂为黑色或者白色,每一次操作你可以把颜色相同的点所在的连通块编程另一个颜色

问你至少需要多少次操作能把所有节点颜色变成相同地

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

解题思路:我们先举一个列子:1010101,如果我们选择0进行操作,那么就会变为 1011101会发现连通块会变大。

这样一直操作下去,颜色肯定会变成相同地。我们可以先进行缩点操作,这颗树就变成了一个黑白相间的树

然后找出树的直径,选择直径中的中点进行操作即可

代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#define here     cout<<"-1";
#include<string.h>
using namespace std;
const int maxn=3e5+10;
int vis[maxn],col[maxn];
vector<int>q[maxn];
vector<int>g[maxn];
int deep,pos;
void dfs(int x,int fa)
{
    if(vis[x]) return ;
    vis[x]=1;
    if(col[x]!=col[fa]) g[fa].push_back(x),g[x].push_back(fa),fa=x;
    for(int i=0;i<q[x].size();i++) dfs(q[x][i],fa);
}
void dfs2(int x,int dp)
{
    if(vis[x]) return ;
    vis[x]=1;
    if(dp>deep) deep=dp,pos=x;
    for(int i=0;i<g[x].size();i++)
    {
         dfs2(g[x][i],dp+1);    
    } 
} 
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>col[i];
    for(int i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        q[a].push_back(b);
        q[b].push_back(a);
    }
    dfs(1,1);
    memset(vis,0,sizeof(vis));
    dfs2(1,0);
    memset(vis,0,sizeof(vis));
    dfs2(pos,0);
//    cout<<deep<<endl;
    cout<<(deep+1)/2<<endl;
    return 0;
 } 
原文地址:https://www.cnblogs.com/tombraider-shadow/p/12546005.html