题意简述:判断所给图是不是一个k递归图
这是一个2递归图
题解:仔细观察发现中心点一定是直径的中点,因此找到直径中点之后进行bfs判断即可,这里注意判断递归层次太大也不符合
const int maxn=1e5+5; const int maxm=2e5+5; const int inf=1e9; int head[maxn],ver[maxm],nex[maxm],tot; void inline AddEdge(int x,int y){ ver[++tot]=y,nex[tot]=head[x],head[x]=tot; } int n,k; int d[maxn],dep[maxn],pre[maxn]; bool vis[maxn]; int main(){ cin>>n>>k; for(int i=0;i<n-1;i++){ int x,y; scanf("%d%d",&x,&y); AddEdge(x,y); AddEdge(y,x); d[x]++; d[y]++; } int lf=0; for(int i=1;i<=n;i++) if(d[i]==1) { lf=i;break; } if(!lf) { puts("No");return 0; } queue<int> q; q.push(lf); int rf=0; while(q.size()){ int x=q.front();q.pop(); vis[x]=1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(!vis[y]) { dep[y]=dep[x]+1; pre[y]=x; q.push(y); } } } for(int i=1;i<=n;i++){ if(dep[i]==2*k) { rf=i;break; } } if(!rf) { puts("No");return 0; } int rt; for(int i=0;i<k;i++){ rf=pre[rf]; } rt=rf; memset(vis,0,sizeof(vis)); memset(dep,0,sizeof(dep)); q.push(rt); while(q.size()){ int x=q.front();q.pop(); int sum=0; vis[x]=1; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(!vis[y]){ dep[y]=dep[x]+1; pre[y]=x; q.push(y); sum++; } } if(dep[x]<k && sum<3) { puts("No");return 0; } if(dep[x]>k) {//巨坑 puts("No"); return 0; } } puts("Yes"); }