count

count
【问题描述】
李华终于逃离了无尽的英语作文, 重获自由的他对一棵树产生了兴趣。
首先,他想知道一棵树是否能分成大小相同的几块(即切掉一些边,使得每个连通块的点数相同)。然后,他觉得这个问题过于简单,于是他想知道一共有多少种方案可以把这棵树分成大小相同的几块。
然后他发现自己不会了,于是向聪明的你求助。
【输入格式】
第一行一个数,表示数的大小。
第二行至第N行,每行两个数x,y表示x和y之间有一条边。
【输出格式】
一行,表示方案数。
【样例一输入】
6
1 2
2 3
2 4
4 5
5 6
【样例一输入】
3
HINT:
对于30%的数据,1<=n<=100。
对于60%的数据,1<=n<=100000。
对于100%的数据,1<=n<=1000000。

n要被分成大小为k的联通块,那么这棵树一定有n/k个点的子树大小为k或k的倍数.

//只有树大小为k或k的倍数.才能被分为大小k的联通块。

#include<bits/stdc++.h>
using namespace std;
int tp, nex[2000005], h[1000005], tov[2000005], n, siz[2000005], an;
void read(int &x)
{
	int f = 0; x = 0 ; char  c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-') f = 1; c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0'; c = getchar();
	}
	if(f) x = -x;
}
void add(int x,int y)
{
	tp++;
	nex[tp] = h[x];
	tov[tp] = y;
	h[x] = tp;
}
void dfs(int x,int fa)
{
	siz[x]  = 1;
	for(int i = h[x]; i; i = nex[i])
	{
		int v =tov[i];
		if(v == fa) continue;
	    dfs(v,x);
	    siz[x] += siz[v];
	}
}
int main()
{
	freopen("count.in","r",stdin);
	freopen("count.out","w",stdout);
	read(n);
	for(int i = 1; i < n; i++)
	{
		int x,y;
		read(x);read(y);
		add(x,y); add(y,x);
	}
	dfs(1,1);
	for(int i = 1; i  <= n; i++)
	{
		if(n % i == 0)
		{
			int ans =0;
			for(int j = 1; j <= n ; j++) if(siz[j] % i == 0) ans ++;
			if(ans == n/i) an++;
		}
	}
	cout << an;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值