题意
给我一颗有 n 个节点的树,树的编号从 1~n 开始,树的节点有点权,值为 0 的表示节点被染成了 白色,权值为的时候被染成了黑色, 现在我们的给我们提供一种操作(如下图):选择某一个结点 x,让把所有把 x 能直接有路径到达的点设这些点为 y,且 y 与 x 同色,把 x 与所有 y 的颜色进行翻转。
思路
把相邻且颜色相同的点认为是在一个连通分量里面,这个时候如果我们选择一个连通分量对其进行翻转,那么翻转之后这个连通分量与周围的连通分量的颜色变的相同,相当于同化了周围的连通分量,接下来我们只需要在选择这个连通扩大了的连通分量不断进行了操作了。 先用 dfs 对每一个连通分量进行编号,然后对每一个连通分量进行编号,形成一个新的树,而这个新的树是相邻节点是颜色不同, 设这棵树的直径为 mx_len, 那么我们需要的变化次数为 (mx_len+1)/2, 自己画个图看看
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <bitset>
#include <vector>
using namespace std;
void fre ( ) { system ( "clear" ) , freopen ( "A.txt" , "r" , stdin ) ; freopen ( "Ans.txt" , "w" , stdout ) ; }
void Fre ( ) { system ( "clear" ) , freopen ( "A.txt" , "r" , stdin ) ; }
void Run ( int x = 0 ) {
#ifdef ACM
if ( ! x) fre ( ) ; else Fre ( ) ;
#endif
}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define db double
#define ll long long
#define ull unsigned long long
#define Pir pair<ll, ll>
#define m_p make_pair
#define for_(i, s, e) for(ll i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(ll i = (ll)(e); i >= (ll)(s); i --)
#define memset(a, b, c) memset(a, (int)b, c);
#define size() size() * 1LL
#define sc scanf
#define pr printf
#define sd(a) sc("%lld", &a)
#define ss(a) sc("%s", a)
#define __ pr( "------------------------\n" );
#define ___ pr("\n------------------------\n");
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
const ll mxn = 2e5 + 10 ;
ll n, w[ mxn] , vis[ mxn] , cor[ mxn] ;
vector< ll> e[ mxn] , g[ mxn] ;
ll f[ mxn] [ 2 ] , mx_len;
void dfs ( ll u, ll p, ll c, ll id)
{
vis[ u] = id;
for_ ( i, 0 , e[ u] . size ( ) - 1 )
{
ll v = e[ u] [ i] ;
if ( v == p || w[ v] != c) continue ;
dfs ( v, u, c, id) ;
}
}
void make_dot ( )
{
ll id = 0 ;
for_ ( i, 1 , n)
{
if ( ! vis[ i] )
{
dfs ( i, 0 , w[ i] , ++ id) ;
cor[ id] = w[ i] ;
}
}
for_ ( i, 1 , n)
{
for_ ( j, 0 , e[ i] . size ( ) - 1 )
{
ll k = e[ i] [ j] ;
if ( w[ i] != w[ k] )
{
g[ vis[ i] ] . pb ( vis[ k] ) ;
}
}
}
}
void DFS ( ll u, ll p)
{
for_ ( i, 0 , g[ u] . size ( ) - 1 )
{
ll v = g[ u] [ i] ;
if ( v == p) continue ;
DFS ( v, u) ;
ll tmp = 1 + f[ v] [ 0 ] ;
if ( tmp >= f[ u] [ 0 ] ) f[ u] [ 1 ] = f[ u] [ 0 ] , f[ u] [ 0 ] = tmp;
else if ( tmp > f[ u] [ 1 ] ) f[ u] [ 1 ] = tmp;
}
mx_len = max ( mx_len, f[ u] [ 0 ] + f[ u] [ 1 ] ) ;
}
int main ( )
{
Run ( ) ;
sd ( n) ;
for_ ( i, 1 , n) sd ( w[ i] ) ;
ll u, v;
for_ ( i, 2 , n)
{
sc ( "%lld %lld" , & u, & v) ;
e[ u] . pb ( v) ;
e[ v] . pb ( u) ;
}
make_dot ( ) ;
DFS ( 1 , 0 ) ;
pr ( "%lld\n" , ( mx_len + 1 ) / 2 ) ;
return 0 ;
}