设为首页 加入收藏

TOP

hdu 5379 Mahjong tree(树形dp)
2015-11-21 00:54:53 来源: 作者: 【 】 浏览:1
Tags:hdu 5379 Mahjong tree 树形

?

树形dp,每个节点最多有2个子节点为一棵节点数大于1的子树的根节点,而且要么后代的节点值都大于,要么都小于本身(所以tson不为0是,要乘2)。对于K个单一节点的子节点,种类数即为全排K!。当一个节点没有兄弟节点时,以这个节点为根结点的子树,根可以选择最大或者最小。

?

?

#pragma comment(linker, /STACK:102400000,102400000)
#include 
  
   
#include 
   
     #include 
    
      #include 
     
       using namespace std; typedef long long ll; const int maxn = 100005; const int mod = 1e9 + 7; int N, son[maxn], tson[maxn], out[maxn], fac[maxn]; vector
      
        G[maxn]; int dfs (int u, int f) { son[u] = tson[u] = 0; ll ret = out[u] = 1; //printf(%d %I64d , u, ret); for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; ret = ret * dfs(v, u) % mod; son[u]++; out[u] += out[v]; if (out[v] > 1) tson[u]++; } ret = ret * fac[son[u] - tson[u]] % mod; if (tson[u]) ret = ret * 2 % mod; //printf(%d:%d %d %I64d , u, son[u], tson[u], ret); if (tson[u] > 2) ret = 0; return ret; } void init () { scanf(%d, &N); for (int i = 1; i <= N; i++) G[i].clear(); /* memset(son, 0, sizeof(son)); memset(out, 0, sizeof(out)); memset(tson, 0, sizeof(tson)); */ int u, v; for (int i = 1; i < N; i++) { scanf(%d%d, &u, &v); G[u].push_back(v); G[v].push_back(u); } } int main () { fac[0] = fac[1] = 1; for (int i = 2; i <= 100000; i++) fac[i] = 1LL * i * fac[i-1] % mod; int cas; scanf(%d, &cas); for (int kcas = 1; kcas <= cas; kcas++) { init (); if (N == 1) printf(Case #%d: 1 , kcas); else printf(Case #%d: %I64d , kcas, 2LL * dfs(1, 0) % mod); } return 0; } 
      
     
    
   
  


?

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 5378 Leader in Tree Land(d.. 下一篇HDOJ 2682 Tree(最小生成树prim算..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: