一点细节没写好结果疯了.....
按照求树直径那样出子树内的最远距离
然后换根求子树外的最远距离
所以数组设置为无穷小,因为我们要求的是最大
#include <bits/stdc++.h> using namespace std; const int maxn=2e5+10; int n,m,x; struct edge{ int to,nxt; }d[maxn]; int head[maxn],cnt=1; void add(int u,int v){ d[++cnt]=(edge){v,head[u]},head[u]=cnt; } int ok[maxn],vis[maxn],f[maxn],g[maxn],pre[maxn],dp[maxn]; void dfs(int u,int fa) { if( ok[u] ) f[u]=g[u]=0; for(int i=head[u];i;i=d[i].nxt ) { int v=d[i].to; if( v==fa ) continue; dfs(v,u); if( f[v]+1>=f[u] )//比最大值还大 g[u]=f[u],f[u]=f[v]+1,pre[u]=v; else if( f[v]+1>g[u] ) g[u]=f[v]+1; } } void back(int u,int fa) { for(int i=head[u];i;i=d[i].nxt ) { int v=d[i].to; if( v==fa ) continue; if( pre[u]==v ) // if( f[u]==f[v]+1 ) dp[v]=max( dp[u]+1,g[u]+1 ); else dp[v]=max( dp[u]+1,f[u]+1 ); back(v,u); } } int main() { cin >> n >> m >> x; for(int i=1;i<=n;i++) f[i]=g[i]=dp[i]=-1e9; for(int i=1;i<=m;i++) { int x; cin >> x; ok[x]=1; } for(int i=1;i<n;i++) { int l,r; cin >> l >> r; add(l,r); add(r,l); } dfs(1,0); back(1,0); int ans=(f[1]<=x); for(int i=2;i<=n;i++) ans += (dp[i]<=x&&f[i]<=x ); cout << ans; }