codeforces 337D D. Book of Evil(树形dp)
来源:互联网 发布:2017淘宝怎么刷才安全 编辑:程序博客网 时间:2024/05/10 13:38
题目链接:
codeforces 337D
题目大意:
给出一棵树,给出感染物的感染范围,给出一些已经确定被感染的点,问感染物可能放置的点的个数。
题目分析:
- 定义状态dp[i]代表某个点到达离它最远的确定的感染点的距离。
- 然后我们首先dfs一遍,求得以1为根的树,每个点到子树中的感染点的最大距离,然后再dfs一遍,求得dp[i]所要求的值,利用一个dd[i]数组表示第i点的父亲,除了自己及以自己为根的子树的点的感染点到自己的最远距离。
- 然后处理出来每个点儿子的前缀和后缀的最大值,然后利用dd就可以求取dp[i],具体转移过程见代码,比较简单,不清楚的地方评论区。。。
AC代码:
#include <iostream># include <cstring>#include <cstdio>#include <algorithm>#include <vector>#define MAX 100007#define INF (-(1<<29));using namespace std;int n,m,d;int dp[MAX];int dd[MAX];int mark[MAX];int lef[MAX],rig[MAX];vector<int> e[MAX];void add ( int u , int v ){ e[u].push_back ( v ); e[v].push_back ( u );}void dfs ( int u , int p ) { if ( mark[u] ) dp[u] = 0; else dp[u] = INF; for ( int i = 0 ; i < e[u].size() ; i++ ) { int v = e[u][i]; if ( v == p ) continue; dfs ( v , u ); dp[u] = max ( dp[u] , dp[v] + 1 ); }}void dfs1 ( int u , int p ){ lef[0] = INF; rig[e[u].size()+1] = INF; for ( int i = 0 ; i < e[u].size() ; i++ ) { int x = i+1; int v = e[u][i]; if ( v == p ) { lef[x] = lef[x-1]; continue; } lef[x] = max ( lef[x-1] , dp[v] ); } for ( int i = e[u].size()-1 ; i >= 0 ; i-- ) { int x = i+1; int v = e[u][i]; if ( v == p ) { rig[x] = rig[x+1]; continue; } rig[x] = max ( rig[x+1] , dp[v] ); } for ( int i = 0 ; i < e[u].size() ; i++ ) { int v = e[u][i]; if ( v == p ) continue; dd[v] = max ( dd[u] , max ( lef[i], rig[i+2])+1 )+1; dp[v] = max ( dp[v] , dd[v] ); } for ( int i = 0 ; i < e[u].size() ; i++ ) { int v = e[u][i]; if ( v == p ) continue; dfs1 ( v , u ); } }void Clear (){ for ( int i = 0 ; i < MAX ; i++ ) e[i].clear();}int main ( ){ while ( ~scanf ( "%d%d%d" , &n , &m, &d ) ) { int x,y; Clear(); memset ( mark , 0 , sizeof ( mark ) ); memset ( dd , -0x3f , sizeof ( dd ) ); for ( int i = 0 ; i < m ; i++ ) { scanf ( "%d" , &x ); mark[x] = 1; } for ( int i = 1 ; i < n ; i++ ) { scanf ( "%d%d" , &x , &y ); add ( x, y ); } dfs ( 1 , -1 ); if ( mark[1] ) dd[1] = 0; else dd[1] = INF; dfs1 ( 1 , -1 ); int ans = 0; for ( int i = 1 ; i <= n ; i ++ ) if ( dp[i] <= d && dp[i] >= 0 ) ans++; printf ( "%d\n" , ans ); }}
0 0
- codeforces 337D D. Book of Evil(树形dp)
- codeforces 337D D. Book of Evil (树形 dp)
- 【树形DP】 codeforces 337D Book of Evil
- Codeforces-337D Book of Evil【树形dp】
- 树形dp-CF-337D. Book of Evil
- CodeForces #196(Div. 2) 337D Book of Evil (树形dp)
- Codeforces 337 D Book of Evil(树形dp,两遍dfs)
- Codeforces 337D Book of Evil【树形Dp】好题~好题~
- codeforces 337D Book of Evil
- 337D Book of Evil
- CodeForces Round #196 D Book of Evil
- Codeforces 337D Book of Evil 树状DP 或 BFS找子树直径端点
- Codeforces 337D Book of Evil 【树,dfs】
- Codeforces 337D Book of Evil (树的直径)
- CodeForces 337D——Book of Evil(数据结构)
- CodeForces 337D Book of Evil(双向dfs)
- CF-337D Book of Evil
- cordeforces 337D Book of Evil
- 学习ThinkPHP3.2.2:video9,对3.1的分组与3.2.2的模块的理解
- Java与C#的区别
- C++ 内存分配(new,operator new)详解
- nyoj 1057 寻找最大数
- Android连接网络
- codeforces 337D D. Book of Evil(树形dp)
- POJ 1006 Biorhythms(中国剩余定理 模板)
- 学习ThinkPHP3.2.2:video9,function的作用范围
- 【bzoj2441】 中山市选2011小W的问题 线段树
- HDU 3723 Delta Wave(2010 Asia Tianjin Regional Contest )
- DirectX11 把纹理作为材质
- 按下计算机电源键的一刻发生了什么(1)?
- 学习ThinkPHP3.2.2:video10,可以通过设置 TMPL_FILE_DEPR 简化模板文件目录层次
- 学习ThinkPHP3.2.2:video10,设置模板读取控制器中某个操作的url