题目链接 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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-30 07:44:38