题意:
给出一棵树。
定义一个叶子集合为:
集合中任意一对叶子之间的距离小于等于k
做法:
考虑每次从最深的点开始搜索,这样可以保证,搜K次搜到的点之间的距离不超过K。
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+100; int n,k,rt; int dep[maxn]; vector<int> g[maxn]; int vis[maxn]; int p[maxn]; int cmp (int x,int y) { return dep[x]>dep[y]; } void dfs1 (int x,int f) { dep[x]=dep[f]+1; for (int y:g[x]) if (y!=f) dfs1(y,x); } void dfs2 (int x,int f,int d) { vis[x]=1; //printf("%d ",x); if (d==k) return; for (int y:g[x]) if (y!=f) dfs2(y,x,d+1); } int main () { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) p[i]=i; for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); if (!rt&&g[x].size()>1) rt=x; if (!rt&&g[y].size()>1) rt=y; } dfs1(rt,0); sort(p+1,p+n+1,cmp); //for (int i=1;i<=n;i++) printf("%d ",p[i]); //printf(" "); int ans=0; for (int i=1;i<=n;i++) { if (vis[p[i]]) continue; if (g[p[i]].size()>1) continue; ans++; dfs2(p[i],0,0); //printf(" "); } printf("%d ",ans); }
这是一个重要的结论,可能会碰到相似的模型。