codeforces 337D Book of Evil (树形dp)
题目链接:http://codeforces.com/problemset/problem/337/D
参考博客:http://www.cnblogs.com/chanme/p/3265913
题目大意:给你一个n个点的无向树。任意两点的距离为中间经过的边数。现在某个点上有本魔法书,这本书对与这个点距离小于等于d的点有影响。给你收集到的m个受影响的点(信息不一定全对)。要你判断有多少个点可能放魔法书。
算法思路:我参考别人的想法,自己开始怎么也想不出好的算法,n也太大。这题用树形dp,两遍dfs来统计出每一个点到所有这个m个受影响点的距离的最大值。只要这个最大值<=d,就可能放魔法书。 所以关键就是算这个最大值,有树形dp第一遍就可以统计以u为根,u到子树中存在的受影响点的最大值。第二遍要利用父亲和兄弟节点来求出u到剩余受影响点(即不在u的子树上的点)的最大值。然后和在一起就是u到所有受影响点的最大值。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = ;
const int INF = 0x3f3f3f3f; int disDown[maxn]; //disDown[u]表示以u为根的子树Pm中的点到u距离的最大值。
int disUp[maxn]; //disUp[u]表示以u为根去掉上面的子树中的点,u到与父亲相连的所有pm的最大值。
int Max[maxn]; //Max[u]表示u为根子树Pm中的点到u距离的最大值。
int SecMax[maxn]; //SecMax[u]表示u为根子树Pm中的点到u距离的第二大值。
int n,m,d;
vector<int> G[maxn]; void dfs1(int u,int fa)
{
for(int i=,sz=G[u].size(); i<sz; i++)
{
int v = G[u][i];
if(v == fa) continue; dfs1(v,u);
if(disDown[v]+ > SecMax[u])
{
SecMax[u] = disDown[v] + ;
if(SecMax[u] > Max[u])
swap(SecMax[u],Max[u]);
}
}
disDown[u]=max(disDown[u],Max[u]);
} void dfs2(int u,int fa)
{
for(int i=,sz=G[u].size(); i<sz; i++)
{
int v = G[u][i];
if(v == fa) continue; if(disDown[v] + == Max[u])
disUp[v] = max( disUp[v] , max(disUp[u],SecMax[u])+ ); else
disUp[v] = max( disUp[v] , max(disUp[u],Max[u])+ ); dfs2(v,u);
}
} int main()
{
//freopen("E:\\acm\\input.txt","r",stdin);
cin>>n>>m>>d; memset(disDown,-0x3f,sizeof(disDown));
memset(disUp,-0x3f,sizeof(disUp));
memset(Max,-0x3f,sizeof(Max));
memset(SecMax,-0x3f,sizeof(SecMax)); for(int i=; i<=m; i++)
{
int pm;
scanf("%d",&pm);
disDown[pm] = disUp[pm] = ;
} for(int i=; i<=n; i++) G[i].clear();
for(int i=; i<n; i++)
{
int u,v;
scanf("%d %d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
} dfs1(,-);
dfs2(,-); int ans = ;
for(int i=; i<=n; i++)
if(disDown[i] <= d && disUp[i] <= d)
ans ++;
printf("%d\n",ans);
}
codeforces 337D Book of Evil (树形dp)的更多相关文章
- CF 337D Book of Evil 树形DP 好题
Paladin Manao caught the trail of the ancient Book of Evil in a swampy area. This area contains n se ...
- codeforce 337D Book of Evil ----树形DP&bfs&树的直径
比较经典的老题 题目意思:给你一颗节点数为n的树,然后其中m个特殊点,再给你一个值d,问你在树中有多少个点到这m个点的距离都不大于d. 这题的写法有点像树的直径求法,先随便选择一个点(姑且设为点1)来 ...
- codeforces 161D Distance in Tree 树形dp
题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...
- Codeforces 1276D - Tree Elimination(树形 dp)
Codeforces 题面传送门 & 洛谷题面传送门 繁琐的简单树形 dp(大雾),要是现场肯定弃了去做 F 题 做了我一中午,写篇题解纪念下. 提供一种不太一样的思路. 首先碰到这样的题肯定 ...
- Codeforces 543D Road Improvement(树形DP + 乘法逆元)
题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...
- Codeforces 337D Book of evil
一道树形dp,写出来是因为最近也做了道类似的.这题是看了分析的思路才做出来的,但感觉很多这样的dp都是利用类似的性质.像这题的话distDown很好想,但distUp的时候就很难想了,其实只要抓住di ...
- Codeforces 815C Karen and Supermarket 树形dp
Karen and Supermarket 感觉就是很普通的树形dp. dp[ i ][ 0 ][ u ]表示在 i 这棵子树中选择 u 个且 i 不用优惠券的最小花费. dp[ i ][ 1 ][ ...
- Codeforces 627D Preorder Test(二分+树形DP)
题意:给出一棵无根树,每个节点有一个权值,现在要让dfs序的前k个结点的最小值最大,求出这个值. 考虑二分答案,把>=答案的点标记为1,<答案的点标记为0,现在的任务时使得dfs序的前k个 ...
- Codeforces 919D Substring (拓扑排序+树形dp)
题目:Substring 题意:给你一个有向图, 一共有n个节点 , m条变, 一条路上的价值为这个路上出现过的某个字符最多出现次数, 现求这个最大价值, 如果价值可以无限大就输出-1. 题解:当这个 ...
随机推荐
- PHP语言、浏览器、操作系统、IP、地理位置、ISP
)]; } else { $Isp = 'None'; } return $Isp; }}
- iOS 此证书的签发者无效
1.先检查Apple Worldwide Developer Relations Certification Authority Intermediate Certificate证书是否过期,该证书过 ...
- asp.net mvc Ajax服务器跳转
1.过滤器权限验证 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowM ...
- c#数组的交集,差集,并集
, , , , }; , , , , }; // 差集 var z1 = x.Except(y); foreach (var i in z1) { Console.Write(i + " & ...
- JavaScript 快速入门回顾
数据类型Number JavaScript不区分整数和浮点数,统一用Number表示,以下都是合法的Number类型: 123; // 整数123 0.456; // 浮点数0.456 1.2345e ...
- Open judge 06月度开销
06:月度开销 总时间限制: 1000ms 内存限制: 65536kB 传送门 描述 农夫约翰是一个精明的会计师.他意识到自己可能没有足够的钱来维持农场的运转了.他计算出并记录下了接下来 N (1 ≤ ...
- [转载] CMake Official Tutorial——教程还是官方的好
CMake官方教程传送门:https://cmake.org/cmake-tutorial/ 以下的内容跟官方教程基本一致,少数地方根据自己的测试有所改动: A Basic Starting Poin ...
- Data Abstraction
What is an object? (Page 238) In C++, an object is just a variable, and the purest definition is &qu ...
- pip 的 Assert Error
在Ubuntu 14.04 中安装了Python之后,使用pip freeze,出现AssertError. 发现是pip版本太低,只有1.5.6 更新pip之后就OK了.
- 如何用.NET创建Windows服务
我们将研究如何创建一个作为Windows服务的应用程序.内容包含什么是Windows服务,如何创建.安装和调试它们.会用到System.ServiceProcess.ServiceBase命名空间的类 ...