题解——count(树上切割)

题解——count(树上切割)

今天考试T1,和我之前写的一篇叫做草莓的题解有点像


题面

Description
求一共有多少种方案可以把一棵树分成大小相同的几块。
Input
第一行一个数N,表示数的大小。
第二行至第N行,每行两个数x,y表示x和y之间有一条边。
Output
一行,表示方案数。
Sample Input
6
1 2
2 3
2 4
4 5
5 6
Sample Output
3

思路

我们考虑,如果数 Ai 能够满足将一棵树切割为若干大小相同的块,那么首先 Ai 必须是 N 的因数。(在1e6的数据内,最大的因数个数是一个较小的3位数)。然后,像草莓那道题一样,枚举每个因数,只要存在能将一个子树大小刚为因数的,我们就将这个子树减去。如果子树大小超了,那么肯定无法减去。

题解传送门:题解——草莓`

AC code: 我写的相当简洁

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1000005 ;
inline int read(){
	int s=0 ;char g=getchar() ; while( g>'9'||g<'0')g=getchar() ;
	while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
}
int N , size[ MAXN ] , head[ MAXN ] ,to[ MAXN*2 ] , nex[ MAXN*2 ] , ans = 0 , tot = 1 ;
bool key ;
void  add( int x , int y ){
	to[ ++tot ] = y , nex[ tot ] = head[ x ] , head[ x ] = tot ;
}
void  dfs( int u , int fa , int val ){
	if( !key )return ;//剪枝 
	size[ u ] = 1 ;//本身 
	for( register int i = head[ u ] ; i ; i = nex[ i ] ){
		if( to[ i ] == fa )continue ; 
		dfs( to[ i ] , u , val ) ;
		size[ u ] += size[ to[ i ] ] ;	
	}
	if( size[ u ] == val )size[ u ] = 0 ;
	if( size[ u ] > val ){key = false ; return ;}
}
int  main(){
	N = read() ; int m1 , m2 ; 
	for( register int i = 1 ; i < N ; ++i ){
		m1 = read() , m2 =read() ;
		add( m1 , m2 ) , add( m2 ,m1 ) ;
	}
	ans = 1 ; // 1 
	for( register int i = 2 ; i <= N ; ++i )
	    if( !( N%i ) ){
	    	key = true ; 
	    	dfs( 1 , 1 , i ) ;
	    	if( key ){
	    		ans++ ;
			}
		}
	cout<<ans ; 
	return 0 ;
}
}

如有不足,请大佬指出

posted @ 2019-08-22 14:23  蓝银杏-SSW  阅读(154)  评论(0编辑  收藏  举报
//结束