题意
你有一棵有个节点树,其中有个已告知的标记点,求个点中,有多少个点到这个标记点的最大距离不大于。
分析
。所以我们可以处理一下,跑两次,分别把子树内和子树外两种情况处理出来,最后统计答案时,两者同时满足就可以纳入。
代码
#include<bits/stdc++.h> #define ll long long const int N=1e5+5,INF=0x3f3f3f3f,mod=998244353; using namespace std; int n,m,d,cnt,py,ans,u,v; int head[N],dis[N][2],gw[N]; struct node { int nxt,to; }e[N<<1]; inline int read() { register int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar(); return x*f; } int qpow(int a,int b) { int ans=1; while(b){if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans; } inline void add(int u, int v) { e[++cnt].nxt=head[u]; e[cnt].to=v; head[u]=cnt; } void dfs(int u,int fa,int dep,int f) { dis[u][f]=dep; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].to; if(v!=fa)dfs(v,u,dep+1,f); } } int main() { n=read(),m=read(),d=read(); for(int i=1;i<=m;i++) gw[i]=read(); for(int i=1;i<n;i++) { u=read(),v=read(); add(u,v);add(v,u); } dfs(1,0,0,1); for(int i=1;i<=m;i++) if(dis[gw[i]][1]>dis[py][1]) py=gw[i]; dfs(py,0,0,1); py=0; for(int i=1;i<=m;i++) if(dis[gw[i]][1]>dis[py][1]) py=gw[i]; dfs(py,0,0,2); for(int i=1;i<=n;i++) if(dis[i][1]<=d&&dis[i][2]<=d) ans++; printf("%d", ans); return 0; }