您的位置:首页 > 其它

hdu5379(2015多校7)--Mahjong tree(构造+dfs)

2015-08-18 09:00 260 查看
题目链接:点击打开链接

题目大意:给出一棵n个节点的树,1节点是根,现在有1到n,n个数放到每个节点上,要求每个子树中数字是连续的,同一个父节点的节点数字是连续的,问有多少种。

如果对于一个节点u来说,如果子节点vi数目是sum,子节点是叶子节点的数目是num,如果sum-num>2那么不能被构造,如果sum-num==2,那么方案是dp[u] = ∏dp[vi]*(num!),如果小于2,那么方案是dp[u] = ∏dp[vi]*(num!)*2注意取余

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define maxn 100010
#define LL __int64
const int Mod = 1e9+7 ;
struct node{
int v , next ;
}edge[maxn<<1] ;
int head[maxn] , cnt ;
int leaf[maxn] , flag ;
LL s[maxn] , dp[maxn] ;
void add(int u,int v) {
edge[cnt].v = v ; edge[cnt].next = head[u] ;
head[u] = cnt++ ;
}
void dfs(int u,int fa) {
int i , v , num = 0 , sum = 0 ;
dp[u] = leaf[u] = 1 ;
for(i = head[u] ; i != -1 ; i = edge[i].next) {
v = edge[i].v ;
if( v == fa ) continue ;
leaf[u] = 0 ;
dfs(v,u) ;
dp[u] = dp[u]*dp[v]%Mod ;
sum++ ;
if( leaf[v] ) num++ ;
}
if( sum == 0 ) return ;
if( sum-num > 2 ) flag = 1 ;
if( sum-num == 2 )
dp[u] = dp[u]*s[num]%Mod ;
else
dp[u] = dp[u]*s[num]*2%Mod ;
}
int main() {
int t , step = 0 ;
int n , i , j , u , v ;
s[0] = 1 ;
for(i = 1 ; i <= 100000 ; i++)
s[i] = s[i-1]*i%Mod ;
scanf("%d", &t) ;
while( t-- ) {
scanf("%d", &n) ;
memset(head,-1,sizeof(head)) ;
cnt = 0 ;
for(i = 1; i < n ; i++) {
scanf("%d %d", &u, &v) ;
add(u,v) ;
add(v,u) ;
}
flag = 0 ;
dfs(1,-1) ;
if( flag ) dp[1] = 0 ;
printf("Case #%d: %I64d\n", ++step, dp[1]) ;
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: