$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. 可能是国内最火的开源项目 —— C/C++ 篇

    程序员们,在北上广你还能买房吗? >>>   推荐阅读: 可能是最火的开源项目 -- Java 篇 可能是国内最火的开源项目 -- PHP 篇 可能是国内最火的开源项目 -- Pyt ...

  2. 验证组件——FluentValidation

          FluentValidation FluentValidation是与ASP.NET DataAnnotataion Attribute验证实体不同的数据验证组件,提供了将实体与验证分离开 ...

  3. Jmeter-分布式

    转载自: http://www.51testing.com/html/28/116228-247521.html 由于Jmeter本身的瓶颈,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发 ...

  4. 洛谷 P3375 【模板】KMP字符串匹配

    我这段时间因为字符串太差而被关了起来了(昨晚打cf不会处理字符串现场找大佬模板瞎搞,差点就凉了),所以决定好好补一下字符串的知识QAQ,暂时先学习kmp算法吧~ 题目链接:https://www.lu ...

  5. Vue 键盘事件

    Vue2键盘事件:keydown/keyup... 1.使用 <!DOCTYPE html> <html> <head> <title></tit ...

  6. js 数组&字符串 去重

    Array.prototype.unique1 = function() { var n = []; //一个新的临时数组 for(var i = 0; i < this.length; i++ ...

  7. 一个python拖库字段的小脚本

    import requests import re all_column = dict() all_db = "db_zf,dg_activity,dg_activity_log,dg_ad ...

  8. linux编程之文件操作

    在linux下用文件描述符来表示设备文件盒普通文件,文件描述符是一个整型的数据,所有对文件的操作都是通过文件描述符来实现的. 文件描述符是文件系统中连接用户空间和内核空间的枢纽,当我们打开一个或者创建 ...

  9. C++之指针,引用与数组

    引用只是对象的另一个名字,通过在变量名前面添加"&”符号来定义,而指针保存的是另一个对象的地址,它们两都提供了间接访问所服务变量的途径. 但是它们的差别还是挺大的: 先从它们的值说起 ...

  10. STM32-内存管理

    转载:http://www.cnblogs.com/guozhikai/p/6031904.html #ifndef __MALLOC_H #define __MALLOC_H #include &q ...