Codeforces Round #196 (Div. 2) D:http://codeforces.com/contest/337/status/D
题意:给你一个树,然后树中有一m个点,求到这m个点距离都小于=d的点的个数。
题解:有一个重要的性质就是,树上距离任意一点到最远距离的点一定在树的直径的端点之一。所以此时,只要求出所有点到树的直径两个端点距离的最大值就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 const int N=1e5+10; 8 vector<int>Q[N]; 9 int n,m,d,maxn,start,temp,u,v,ans; 10 int dis[N]; 11 bool vis[N]; 12 void DFS(int u,int fa,int len){ 13 dis[u]=max(dis[u],len); 14 if(vis[u]&&dis[u]>maxn){ 15 start=u; 16 maxn=dis[u]; 17 } 18 for(int i=0;i<Q[u].size();i++){ 19 int v=Q[u][i]; 20 if(v!=fa) 21 DFS(v,u,len+1); 22 } 23 } 24 int main(){ 25 scanf("%d%d%d",&n,&m,&d); 26 for(int i=1;i<=n;i++) 27 Q[i].clear(); 28 memset(vis,0,sizeof(vis)); 29 for(int i=1;i<=m;i++){ 30 scanf("%d",&temp); 31 vis[temp]=1; 32 start=temp; 33 } 34 for(int i=1;i<n;i++){ 35 scanf("%d%d",&u,&v); 36 Q[u].push_back(v); 37 Q[v].push_back(u); 38 } 39 memset(dis,0,sizeof(dis)); 40 maxn=0; 41 DFS(start,0,0); 42 maxn=ans=0; 43 DFS(start,0,0); 44 DFS(start,0,0); 45 for(int i=1;i<=n;i++){ 46 if(dis[i]<=d) 47 ans++; 48 } 49 printf("%d ",ans); 50 51 }