题目链接 http://codeforces.com/contest/337/problem/D
题意:给一棵n个结点的树,边权都为1。在树上的某个结点有一个“恶魔之书”,这
本书会让距离它d以内的节点都受到影响。现在已知有m个节点收到了影响,问最
多有几个结点可能放着“恶魔之书”?
思路:首先我们需要找出受到影响的点中,两两距离最远的一对点,之后,只需要
计算有多少个点到这两个点的距离都小于d。这样就能求出答案。
找出最远点对的方法:我们首先以1节点为根节点,算出每个点的此时的深度,然
后找出受影响的点中,深度最大的一个节点u;再以这个节点为根节点重新算一次
每个点的深度,同样找出此时受影响的点中深度最大的一个点v。那么此时u,v这
两个点一定是最远点对。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn=100010;
vector <int> G[maxn];
int n,m,d,a[maxn],dp[maxn],b[maxn],c[maxn];
void dfs(int u,int fa)
{
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==fa) continue;
dp[v]=dp[u]+1;
dfs(v,u);
}
}
int main()
{
int u,v;
scanf("%d %d %d",&n,&m,&d);
for(int i=0;i<m;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dp[1]=0;
dfs(1,-1);
int s=a[0],t=a[0];
for(int i=1;i<m;i++) if(dp[s]<dp[a[i]]) s=a[i];
dp[s]=0;
dfs(s,-1);
memcpy(b,dp,sizeof(dp));
for(int i=1;i<m;i++) if(dp[t]<dp[a[i]]) t=a[i];
dp[t]=0;
dfs(t,-1);
memcpy(c,dp,sizeof(dp));
int ans=0;
for(int i=1;i<=n;i++) if(b[i]<=d && c[i]<=d) ans++;
cout<<ans<<endl;
}