Book of Evil

Paladin Manao caught the trail of the ancient Book of Evil in a swampy area. This area contains n settlements numbered from 1 to n. Moving through the swamp is very difficult, so people tramped exactly n - 1 paths. Each of these paths connects some pair of settlements and is bidirectional. Moreover, it is possible to reach any settlement from any other one by traversing one or several paths.

The distance between two settlements is the minimum number of paths that have to be crossed to get from one settlement to the other one. Manao knows that the Book of Evil has got a damage range d. This means that if the Book of Evil is located in some settlement, its damage (for example, emergence of ghosts and werewolves) affects other settlements at distance d or less from the settlement where the Book resides.

Manao has heard of m settlements affected by the Book of Evil. Their numbers are p1, p2, ..., pm. Note that the Book may be affecting other settlements as well, but this has not been detected yet. Manao wants to determine which settlements may contain the Book. Help him with this difficult task.

Input

The first line contains three space-separated integers nm and d (1 ≤ mn ≤ 100000; 0 ≤ dn - 1). The second line contains mdistinct space-separated integers p1, p2, ..., pm (1 ≤ pin). Then n - 1 lines follow, each line describes a path made in the area. A path is described by a pair of space-separated integers ai and bi representing the ends of this path.

Output

Print a single number — the number of settlements that may contain the Book of Evil. It is possible that Manao received some controversial information and there is no settlement that may contain the Book. In such case, print 0.

Sample test(s)
input
6 2 3
1 2
1 5
2 3
3 4
4 5
5 6
output
3
Note

Sample 1. The damage range of the Book of Evil equals 3 and its effects have been noticed in settlements 1 and 2. Thus, it can be in settlements 3, 4 or 5.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <queue>
#include <cstdlib>
#include <ctime>
#include <stack>
#include <bitset>
#include <fstream> typedef unsigned long long ull;
#define mp make_pair
#define pb push_back const long double eps = 1e-9;
const double pi = acos(-1.0);
const long long inf = 1e18; using namespace std; int n, m, d;
int f[ 100100 ], g[ 100100 ];
vector< int > graf[ 100100 ];
bool ok[ 100100 ]; void dfs1( int v, int p )
{
//cout << v << " " << p << endl;
f[v] = -1;
for ( int i = 0; i < graf[v].size(); i++ )
{
int next = graf[v][i]; if ( next == p ) continue;
dfs1( next, v );
f[v] = max( f[v], ( f[next] == -1 ? -1 : f[next] + 1 ) );
}
if ( ok[v] ) f[v] = max( 0, f[v] );
} void dfs2( int v, int p, int root )
{
g[v] = root;
vector< int > sons;
sons.pb( ( root == -1 ? -1 : root + 1 ) );
if ( ok[v] ) sons.pb( 1 );
for ( int i = 0; i < graf[v].size(); i++ )
{
int next = graf[v][i]; if ( next == p ) continue;
sons.pb( ( f[next] == -1 ? -1 : f[next] + 2 ) );
}
sort( sons.begin(), sons.end(), greater<int>() );
for ( int i = 0; i < graf[v].size(); i++ )
{
int next = graf[v][i]; if ( next == p ) continue;
int nroot = sons[1];
if ( ( f[next] == -1 ? -1 : f[next] + 2 ) != sons[0] ) nroot = sons[0];
dfs2( next, v, nroot );
}
} int main (int argc, const char * argv[])
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
scanf("%d%d%d", &n, &m, &d);
for ( int i = 1; i <= m; i++ )
{
int a; scanf("%d", &a);
ok[a] = true;
}
for ( int i = 1; i < n; i++ )
{
int a, b; scanf("%d%d", &a, &b);
graf[a].pb(b);
graf[b].pb(a);
}
dfs1( 1, -1 );
dfs2( 1, -1, -1 );
int ans = 0;
for ( int i = 1; i <= n; i++ ) if ( max( f[i], g[i] ) <= d ) ans++;
//for ( int i = 1; i <= n; i++ ) cout << i << " " << f[i] << " " << g[i] << endl;
cout << ans << endl;
return 0;
}

Book of Evil 树双向DFS的更多相关文章

  1. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

  2. [2]树的DFS序

    定义: 树的DFS序就是在对树进行DFS的时候,对树的节点进行重新编号:DFS序有一个很强的性质: 一颗子树的所有节点在DFS序内是连续的一段, 利用这个性质我们可以解决很多问题. 代码: void ...

  3. 树的dfs序 && 系统栈 && c++ rope

    利用树的dfs序解决问题: 就是dfs的时候记录每个节点的进入时间和离开时间,这样一个完整的区间就是一颗完整的树,就转化成了区间维护的问题. 比如hdu3887 本质上是一个求子树和的问题 #incl ...

  4. CF877E Danil and a Part-time Job 线段树维护dfs序

    \(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...

  5. HDU 1269.迷宫城堡-Tarjan or 双向DFS

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)

    Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...

  7. HDU 1401 Solitaire 双向DFS

    HDU 1401 Solitaire 双向DFS 题意 给定一个\(8*8\)的棋盘,棋盘上有4个棋子.每一步操作可以把任意一个棋子移动到它周围四个方向上的空格子上,或者可以跳过它四个方向上的棋子(就 ...

  8. 送礼物(二分加双向DFS)

    题目链接 题意:给你n个礼物重量,给你一个M力量,看你一次性搬动不超过M的礼物重量. 思路:看似背包,但M太大.所以要用DFS,但n也有45,所以考虑双向DFS先搜前半部分满足情况的所有重量,然后去重 ...

  9. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

随机推荐

  1. linq中的cast<T>()及OfType<T>()

    DataTable dt=...........//获取从数据库中取出的数据(假设只有一条记录) //Cast<T>()用来将非泛型的序列转换为泛型的序列 DataRow row=dt.R ...

  2. JavaSE复习日记 : 继承关系和super关键字以及继承关系中方法的覆写

    /* * 类的继承和super关键字 * * 软件开发的三大目的: * 可拓展性; * 可维护性; * 可重用性; * * 这里单说下可重用性这一项: * 为了代码复用,复用方式有: * 函数的调用复 ...

  3. CSS截取字符串

    /*溢出的字...处理*/ .updatecsssubstring { text-overflow: ellipsis; -o-text-overflow: ellipsis; white-space ...

  4. Java中的流程控制(一)

    程序的流程控制(一) 关于Java程序的流程控制(一) 从结构化程序设计角度出发,程序有三种结构: 顺序结构 选择结构 循环结构 1.顺序结构 就是程序从上到下一行行执行,中间没有判断和跳转. 2.i ...

  5. python 时间字符串与日期转化

    python 时间字符串与日期转化 datetime.datetime.strptime(string, format) 根据指定的格式解析字符串为一个datetime类型.相当于datetime.d ...

  6. pyVmomi入门

    简要说明 pyVmomi is the Python SDK for the VMware vSphere API that allows you to manage ESX, ESXi, and v ...

  7. APM代码学习笔记2:编译过程

    make编译 所有位置的Makefile 引用的都是/mk/apm.mk target.mk 设置CONFIG_HAL_BOARD 例如linux就是HAL_BOARD_LINUX environ.m ...

  8. 批处理[Batch]

    批处理 1. 定义:就是一堆DOS命令按一定顺序排列而形成的集合. 英文译为BATCH,批处理文件后缀BAT就取的前三个字母. 示例1:a.bat @echo off Netstat –a –n &g ...

  9. Windows Phone 8.1 发送http 网络请求。

    在windows phone 8.1 中可以用 HttpClient 类来发送http 请求. 例子: try { Uri uri = new Uri(@"http://api.map.ba ...

  10. QTreeView处理大量数据(使用1000万条数据,每次都只是部分刷新)

    如何使QTreeView快速显示1000万条数据,并且内存占用量少呢?这个问题困扰我很久,在网上找了好多相关资料,都没有找到合理的解决方案,今天在这里把我的解决方案提供给朋友们,供大家相互学习. 我开 ...