cf1067b

题意简述:判断所给图是不是一个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");
}

  

原文地址:https://www.cnblogs.com/033000-/p/12342829.html