题目链接:http://codeforces.com/problemset/problem/337/D
题意:有n个村庄,其中有m个村庄收到了魔鬼书本的影响,d是书本的最大影响距离,求这个书本可能在的村庄的个数。
题解:这道题就是在m个村庄里找到两个距离最长的村庄,然后分别以这两个村庄为基点求其与其他村庄的距离,两个距离都不大于d的即为可能存在的位置
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 1e5 + 5;
int d1[maxn];
int d2[maxn];
int p[maxn];
vector<int>graph[maxn];
void dfs(int node,int father,int deep, int *d)
{
d[node] = deep;
for(int i = 0; i < graph[node].size(); i ++){
int tmp = graph[node][i];
if(tmp!=father){
dfs(tmp,node,deep+1,d);
}
}
}
int main()
{
int n,m,d;
while(~scanf("%d%d%d",&n,&m,&d)){
memset(d1,0,sizeof(d1));
memset(d2,0,sizeof(d2));
memset(p,0,sizeof(p));
memset(graph,0,sizeof(graph));
for(int i = 1; i <= m; i ++){
scanf("%d",&p[i]);
}
int a, b;
for(int i = 1; i <= n - 1; i ++){
scanf("%d%d",&a,&b);
graph[a].push_back(b);
graph[b].push_back(a);
}
dfs(1,0,0,d1);
int u = 0,max_u = 0;
for(int i = 1; i <= m; i ++){
if(max_u<d1[p[i]]){
max_u = d1[p[i]];
u = p[i];
}
}
dfs(u,0,0,d1);
int v = 0,max_v = 0;
for(int i = 1; i <= m; i ++){
if(max_v<d1[p[i]]){
max_v = d1[p[i]];
v = p[i];
}
}
dfs(v,0,0,d2);
int cnt = 0;
for(int i = 1; i <= n; i ++){
if(d1[i] <= d && d2[i] <= d){
cnt++;
}
}
printf("%d\n",cnt);
}
return 0;
}