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; }