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

Posted SSL_LKJ

tags:

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

树上摩托

题目大意

Sherco是一位经验丰富的魔♂法师。
Sherco在第零次圣杯战争中取得了胜利,并取得了王之宝藏——王の树。
他想把这棵树砍去任意条边,拆成若干棵新树,并装饰在他的摩托上,让他的摩托更加酷炫。
但Sherco认为,这样生成的树不具有美感,于是Sherco想让每棵新树的节点数相同。
他想知道有多少种方法分割这棵树。

输入样例

第一行一个正整数N,表示这棵树的结点总数。
接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相连。结点编号的范围为[1,N]。

6
1 2
2 3
2 4
4 5
5 6

输出样例

一个整数,表示方案数。注意,不砍去任何一条边也算作一种方案。

3

题目数据

对于40%的数据,N ≤ 15
对于60%的数据,N ≤ 10^5
对于100%的数据,N ≤ 10^6
数据规模非常大,请使用高效的读入方式。

解题思路

一些性质

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)(倍增)