2021.8.12提高B组模拟4T2 树上摩托(bfs)

Posted SSL_LKJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.12提高B组模拟4T2 树上摩托(bfs)相关的知识,希望对你有一定的参考价值。

树上摩托

题目大意

输入样例

6
1 2
2 3
2 4
4 5
5 6

输出样例

3

题目数据

解题思路

一些性质

1.树的大小只可能是 N 的约数

2.树的大小确定的话,方案最多只有一种

3.将原树看做一个有根树,一个节点可以作一个块的”根”,当且仅当该节点的 size 能被块的大小整除

预处理出每个节点的 儿子数(包括自己)

枚举树的大小 k(n%k=0)

判断 儿子数 为 k 的倍数的节点数量是否为 n / k n/k n/k

注:记得用bfs,dfs会暴栈

AC代码

#include<iostream>
#include<cstdio>
using namespace std;
int n,t,hd,tail,tot,answer=2,p[1000005],c[1000005],f[1000005],fa[1000005],son[1000005],head[1000005];
struct node

	int to,next;
a[2000005];
void add(int x,int y)

	a[++tot]=(node)y,head[x];
	head[x]=tot;
 
void bfs()//bfs处理出节点的父亲是谁

	c[1]=1;
	p[++tail]=1;
	f[++t]=1;
	while(hd<tail)
	
		int xx=p[++hd];
		for(int i=head[xx];i;i=a[i].next)
			if(a[i].to!=fa[xx])
			
				c[a[i].to]=1;
				fa[a[i].to]=xx;
				f[++t]=a[i].to;
				p[++tail]=a[i].to;
			
	

void getson()//处理出儿子

	for(int i=n;i>=1;i--)
	
		int x=f[i];
		for(int j=head[x];j;j=a[j].next)
			if(a[j].to!=fa[x])
				son[x]+=son[a[j].to];
	

bool check(int x)//通过性质判断是否可行

	int ans=0;
	for(int i=1;i<=n;i++)if(son[i]%x==0)ans++;
	if(ans==n/x)return true;
	return false;

int main()

	scanf("%d",&n);
	if(n==1)
	
		printf("1");
		return 0;
	
	for(int i=1;i<n;i++)
	
		int x,y;
		scanf("%d%d",&x,&y);
		add(y,x);
		add(x,y);
		son[i]=1;//初值
	
	son[n]=1;
	bfs();
	getson();
	for(int i=2;i<n;i++)//求答案
		if(n%i==0)
			if(check(i))answer++;
	printf("%d",answer);
	return 0;


以上是关于2021.8.12提高B组模拟4T2 树上摩托(bfs)的主要内容,如果未能解决你的问题,请参考以下文章

2021.8.12提高B组模拟4T1 幻象(期望dp)

2021.8.12提高B组模拟4T3 矩阵(小根堆)(map判重)

2021.8.12提高B组模拟4T3 矩阵(小根堆)(map判重)

2021.8.12提高B组模拟4T1 幻象(期望dp)

2021.8.10提高B组模拟2T2 祖孙询问(lca)(倍增)

2021.7.14提高B组模拟3T1 树的直径(lca)(倍增)