[9.26 Simulation Game] T2

T2

Description

The room is now being thieves! The thief even has openly come out of the gate! Now we have some information, we hope you can help catch the thief.
The city has assumed within \ (N \) locations, and press \ (1 \) - \ (N \) number. Any two points has one and only one path is connected, the length of each side are \ (1 \) . Now known thief ready after things calm, to \ (M \) mobile phone shop to steal to sell the phone, which \ (M \) mobile phone shop numbers were \ (X1 \) , \ (X2 \) , \ (X3 \) , \ (X4 \) ...... As the thief is very lazy, he's hiding at the distance of each mobile phone shop to no more than \ (D \) .
Now I hope you can help us find the thief might have a few hiding places. ( \ (PS \) : In addition to the first two sentences of this title is purely fictional)

Input

The first row \ (3 \) integers \ (N \) , \ (M \) , \ (D \) . The next line \ (M \) integers, respectively, the number of mobile phone shop. The next \ (N-1 \) rows, each row \ (2 \) integer \ (X-\) , \ (the Y \) . It represents \ (X-\) - \ (the Y \) has an undirected edges.

Output

Row represents the number of possible locations.

Sample Input

6 2 3
1 2
1 5
2 3
3 4
4 5
5 6

Sample Output

3

Data Constraint

For \ (30% \) data \ (. 1 <= N <= 3000 \) ,
for \ (50% \) data \ (. 1 <= N <= 10000 \) , \ (. 1 <= M <= 1000 \)
to \ (100% \) data \ (. 1 <= M <= N <= 30000 \) , \ (0 <= D <=. 1-N \)

Solution

We first find a method similar to the diameter of the tree, we obtain two farthest mobile phone shop \ (A \) and \ (B \) ,
then assuming a point \ (X0 \) , for each point \ (X \) should enable \ (Dist {X, X0} <= D \) , equivalent to \ (Dist {A, x0} <= D \) and \ (Dist {B, x0} <= D \ )
so for \ (a \) and \ (B \) , will find they are less than the distance \ (D \) point, and then find an intersection
and then it is the answer!

Code

#include <iostream>
#define MAXN 30010
using namespace std;
struct rec{
    int ver, nxt;
} t[MAXN << 1];
int cnt, head[MAXN], node, Node, Max, n, m, d, a[MAXN], b[MAXN], flag[MAXN], ans, u, v;

inline int read(){
    int s = 0, w = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    return s * w;
}

void add(int u, int v) {
    t[++cnt] = (rec){v, head[u]}, head[u] = cnt;
}

void DFS(int u, int fa, int sum){
    if (sum > Max && flag[u]) Max = sum, node = u;
    for (register int i = head[u]; i; i = t[i].nxt) {
        int v = t[i].ver;
        if (v != fa) DFS(v, u, sum + 1);
    }
}

void DFS1(int u, int fa, int sum){
    a[u] = 1;
    if (sum == d) return;
    for (register int i = head[u]; i; i = t[i].nxt) {
        int v = t[i].ver;
        if (v != fa) DFS1(v, u, sum + 1);
    }
}

void DFS2(int u, int fa, int sum){
    b[u] = 1;
    if (sum == d) return;
    for (register int i = head[u]; i; i = t[i].nxt) {
        int v = t[i].ver;
        if (v != fa) DFS2(v, u, sum + 1);
    }
}

int main(){
    //freopen("pb.in", "r", stdin);
    //freopen("pb.out", "w", stdout);
    n = read(), m = read(), d = read();
    flag[node = read()] = 1;
    for (register int i = 2; i <= m; i++)
        flag[read()] = 1;
    for (register int i = 1; i <= n - 1; i++)
        u = read(), v = read(), add(u, v), add(v, u);
    Max = -1;
    DFS(node, 0, 0);
    Max = -1, Node = node; 
    DFS(node, 0, 0);
    DFS1(node, 0, 0);
    DFS2(Node, 0, 0);
    for (register int i = 1; i <= n; i++)
        if (a[i] && b[i]) ans++;
    printf("%d\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Agakiss/p/11605962.html