给定一堆点,求到任意的给定点的距离≤d的点有几个?
本题是树的圆的交
需要2个数组distdown[]&distdown[]
表示第i个点向上和向下距离的最远给定点。。。
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (100000+10) #define MAXM (200000+10) long long mul(long long a,long long b){return (a*b)%F;} long long add(long long a,long long b){return (a+b)%F;} long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} typedef long long ll; int n,m,d,distdown[MAXN],distup[MAXN],dismax[MAXN][2]; bool mark[MAXN]={0}; int edge[MAXM],next[MAXM]={0},pre[MAXN]={0},size=1; void modi(int &a,int &b,int c) { if (c>=a) b=a,a=c; else if (c>=b) b=c; } void addedge(int u,int v) { edge[++size]=v; next[size]=pre[u]; pre[u]=size; } void addedge2(int u,int v){addedge(u,v),addedge(v,u);} void dfs1(int x,int fa) { if (mark[x]) distdown[x]=0; Forp(x) { int v=edge[p]; if (v^fa) { dfs1(v,x); if (distdown[v]>=0) { distdown[x]=max(distdown[x],distdown[v]+1); modi(dismax[x][0],dismax[x][1],distdown[v]); } } } } void dfs2(int x,int fa) { if (mark[x]) distup[x]=0; if (fa) { if (distup[fa]>=0) distup[x]=max(distup[x],distup[fa]+1); if (dismax[fa][0]^distdown[x]) distup[x]=max(distup[x],dismax[fa][0]+2); else distup[x]=max(distup[x],dismax[fa][1]+2); } Forp(x) { int &v=edge[p]; if (v^fa) { dfs2(v,x); } } } int main() { // freopen("Evil.in","r",stdin); cin>>n>>m>>d; For(i,m) { int p;cin>>p;mark[p]=1; } MEMi(distdown)MEMi(distup) MEMi(dismax) For(i,n-1) { int u,v; cin>>u>>v; addedge2(u,v); } dfs1(1,0); dfs2(1,0); int ans=0; For(i,n) if (max(distdown[i],distup[i])<=d) ans++;//cout<<i<<' '; cout<<ans<<endl; return 0; }