$dfs$缩点,树形$dp$。

首先将连通块缩点,缩点后形成一个黑白节点相间的树。接下来的任务就是寻找一个$root$,使这棵树以$root$为根,树的高度是最小的(也就是一层一层染色)。树形$dp$可以解决这个问题,第一次$dfs$处理子树,第二次$dfs$枚举$root$计算答案。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0);
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar();
x = ;
while(!isdigit(c)) c = getchar();
while(isdigit(c))
{
x = x * + c - '';
c = getchar();
}
} int n;
int c[];
int nc[];
int u[];
int v[];
int belong[];
int block;
vector<int>G[];
int flag[];
vector<int>L[],R[];
int ans; int a[]; void dfs(int x)
{
belong[x]=block;
for(int i=;i<G[x].size();i++)
{
int to=G[x][i];
if(c[to]!=c[x]) continue;
if(belong[to]!=) continue;
dfs(to);
}
} void dp(int x)
{
flag[x]=; int mx=;
for(int i=;i<G[x].size();i++)
{
int to=G[x][i];
if(flag[to])
{
L[x].push_back(mx);
continue;
} dp(to);
mx=max(mx,a[to]);
L[x].push_back(mx+);
}
a[x]=mx+;
} void dp2(int x)
{
flag[x]=; int mx=;
for(int i=G[x].size()-;i>=;i--)
{
int to=G[x][i];
if(flag[to])
{
R[x].push_back(mx);
continue;
} dp2(to);
mx=max(mx,a[to]);
R[x].push_back(mx+);
}
a[x]=mx+;
} void Find(int x,int h)
{
flag[x]=; int nh;
int sz=G[x].size();
for(int i=;i<G[x].size();i++)
{
int root=G[x][i];
if(flag[root]) continue; nh=h+; int k=;
if(i->=) k=max(k,L[x][i-]);
if(sz-i->=) k=max(k,R[x][sz-i-]);
if(k!=) nh=max(nh,k+); ans=min(ans,max(nh,a[root]));
Find(root,nh);
}
} int main()
{
cin>>n;
for(int i=;i<=n;i++) cin>>c[i];
for(int i=;i<=n-;i++)
{
cin>>u[i]>>v[i];
G[u[i]].push_back(v[i]);
G[v[i]].push_back(u[i]);
} for(int i=;i<=n;i++)
{
if(belong[i]!=) continue;
block++; nc[block]=c[i]; dfs(i);
} for(int i=;i<=n;i++) G[i].clear(); for(int i=;i<=n-;i++)
{
if(c[u[i]]==c[v[i]]) continue;
G[belong[u[i]]].push_back(belong[v[i]]);
G[belong[v[i]]].push_back(belong[u[i]]);
} memset(flag,,sizeof flag); dp();
memset(flag,,sizeof flag); dp2(); ans=a[];
memset(flag,,sizeof flag); Find(,); printf("%d\n",ans-); return ;
}

CodeForces 734E Anton and Tree的更多相关文章

  1. Codeforces 734E. Anton and Tree 搜索

    E. Anton and Tree time limit per test: 3 seconds memory limit per test :256 megabytes input:standard ...

  2. Codeforces 734E Anton and Tree(缩点+树的直径)

    题目链接: Anton and Tree 题意:给出一棵树由0和1构成,一次操作可以将树上一块相同的数字转换为另一个(0->1 , 1->0),求最少几次操作可以把这棵数转化为只有一个数字 ...

  3. Codeforces Round #379 (Div. 2) E. Anton and Tree 缩点 直径

    E. Anton and Tree 题目连接: http://codeforces.com/contest/734/problem/E Description Anton is growing a t ...

  4. Codeforces Round #379 (Div. 2) E. Anton and Tree —— 缩点 + 树上最长路

    题目链接:http://codeforces.com/contest/734/problem/E E. Anton and Tree time limit per test 3 seconds mem ...

  5. Codeforces Round #379 (Div. 2) E. Anton and Tree 树的直径

    E. Anton and Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard i ...

  6. Anton and Tree

    Anton and Tree 题目链接:http://codeforces.com/contest/734/problem/E DFS/BFS 每一次操作都可以使连通的结点变色,所以可以将连通的点缩成 ...

  7. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  8. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  9. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

随机推荐

  1. asyncio 实现 aiohttp

    #asyncio 没有提供http协议的接口 aiohttp import asyncio import socket from urllib.parse import urlparse async ...

  2. jsp 内置对象二

    1.什么是session ? (1)session 表示客户端与服务器的一次回话. 2)Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网 ...

  3. RDLC - 后台代码直接导出Excel/PDF/Word格式

    最近做报表功能,用到了.net的报表组件rdlc. 其中有个功能就是后台代码直接输出Excel/PDF/Word格式的文件,网上看了些资源,做个总结: 参考地址 我直接贴出代码: //自动导出exce ...

  4. python+selenium+js 处理滚动条

    selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了. 常见场景: 当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的. 这时候需要借 ...

  5. js_判断当前url是否合法http(s)

    alert(checkURL('http:555')); //false function checkURL(URL) { var str = URL, Expression = /http(s)?: ...

  6. js按值及引用传递中遇到的小问题

    有人闲的蛋疼,非要在函数中使用如下方式传值,尼玛一下把我搞糊涂了.于是决定发挥打破沙锅问到底的精神搞清楚它. var a = 1,b = [], c = {}; function f(a, b, c) ...

  7. ”未能加载文件或程序集“Oracle.DataAccess”或它的某一个依赖项

    引用:http://www.cnblogs.com/joey0210/archive/2012/09/29/2708420.html 上一篇文章说到了DLL引用问题,主要是说的程序中如果使用过了反射, ...

  8. Python 下调用C动态链接库 -- (转)

    在linux开发的动态链接库需要被python调用,首先需要生成.so文件. 生成动态链接库的方法网上有很多,主要就是首先根据源文件编译生成.o,然后链接这些.o文件-shared生成.so.需要注意 ...

  9. perl 在win下输出中文乱码问题

    use utf8; my $name = '你好'; binmode(STDOUT, ":encoding(gbk)"); print $name,"\n"; ...

  10. linux arm的存储分布那些事之一

    转自:http://blog.csdn.net/xiaojsj111/article/details/11724081   linux arm 内存分布总览   上图是linux的arm的虚拟地址分布 ...