Meaning
to an N-node tree, the distance of any two nodes refers to the shortest number of edges connecting two points.
There is a "demon book" on a node in the tree, and this book will affect the nodes within D.
Known to have m nodes received an impact, ask a maximum of several nodes may have "demon book"?
Ideas
To determine whether a particular point is placed on a book, determine if any of the affected m nodes are included within d distance around the point.
And if a node is farthest from the affected node of the distance is L, if L <= D, then that all the affected m nodes within D, can be judged that this point may be placed in the book
So, we can find out the answer to the time of O (n) as long as we can find out how many nodes are affected by each node at the farthest distance.
So you can use the Tree DP solution:
F (U, 0): The distance from the "affected node" farthest from U in a subtree that represents u as the vertex
F (U, 1): Indicates that the entire tree deletes the subtree of the U-vertex, but still retains the vertex of the U-point, the distance from the farthest "affected node" in the tree
All f (U, 0) can be fixed once DFS, O (n)
F (U, 1) can be pushed down by the top node
F (V, 1) = Max{f[brother1][0], f[brother2][0] ..., f[brother3][0], F [father][1] | Brother is the brother node of V, FA is the parent node of V} + 1
This step can be DFS resolved again, the same is O (n)
Code
/**========================================== * This are a solution for ACM/ICPC problem * * @source: codeforces 337D book O F Evil * @type: Tree DP * @author: Shuangde * @blog: blog.csdn.net/shuangde800 * @email: zengshuangde@gmail.com *============ ===============================*/#include <iostream> #include <cstdio> #include <algorithm> # Include <vector> #include <queue> #include <cmath> #include <cstring> #define MP make_pair using n
Amespace std;
typedef long long Int64;
typedef pair<int,int> PII;
const int INF = 0X3F3F3F3F;
Const double PI = ACOs (-1.0);
const int MAXN = 1E5+10;
namespace adj{int HEAD[MAXN], size; struct node{int V, Next;}
E[MAXN*2+100];
void Initadj () {size = 0; memset (head,-1, sizeof (head));}
void Addedge (int u, int v) {e[size].v = v;
E[size].next = Head[u];
Head[u] = size++;
The using namespace Adj;
int n, m, D;
int f[maxn][2];
BOOL VIS[MAXN], P[MAXN];
int ans; Void dfs (int u) {Vis[u] = true; int& ans = f[u][0] = (P[u]? 0:-1); for (int e = head[u]; e!=-1; e = e[e].next) {in
T v = e[e].v;
if (Vis[v]) continue;
DFS (v);
if (F[v][0]!=-1) ans = max (ans, f[v][0] + 1); The maintenance m1,m2 Save the first big, the second big//http://www.bianceng.cn inline void Update (int w, int V, pii& M1, pii& m2) {if (w
>= m1.first) {m2 = m1; m1.first = w; m1.second = V;} else if (w >= m2.first) {m2.first = W; m2.second = V;}}
void dp (int u) {Vis[u] = true;
PII m1 = MP ( -1, 0), M2=MP (-1, 0);
int tmp = MAX (f[u][0], f[u][1]);
if (TMP!=-1 && tmp <= d) {++ans;}
Update (F[u][1], U, M1, m2); for (int e = head[u]; e!=-1; e = e[e].next) {int v = e[e].v; if (vis[v]) continue; if (f[v][0)!=-1) {Update (f[v][0]+
1, V, M1, M2); for (int e = head[u]; e!=-1; e = e[e].next) {int v = e[e].v; if (vis[v)) continue; f[v][1] =-1; if (v!=m1.sec Ond && m1.first!=-1) {f[v][1] = max (f[v][1], m1.first+1);} else if (M2.firSt!=-1) {f[v][1] = max (f[v][1], m2.first+1); DP (v);
int main () {while (~scanf ("%d%d%d", &n, &m, &d)) {Initadj (); memset (p, 0, sizeof (p));
for (int i = 0; i < m ++i) {int x; scanf ("%d", &x); p[x] = true;}
for (int i = 0; i < n-1 ++i) {int u, v; scanf ("%d%d", &u, &v); Addedge (U, v); Addedge (v, u);
memset (Vis, 0, sizeof (VIS));
DFS (1);
F[1][1] = p[1]?0:-1;
Ans = 0;
memset (Vis, 0, sizeof (VIS));
DP (1);
printf ("%d\n", ans);
return 0; }