任意一棵子树上节点的编号连续,每个节点的所有二字节点连续,求编号方案的总数。

稍微分析一下可知

  • 每个节点的非叶子节点个数不能多于两个,否则这个子树无解,从而整棵树都无解。
  • 每棵子树将所有节点按照编号从小到大排序,根节点要么在最左端,要么在最右端,而且这两种情况相等。(后面会有具体分析)

设size(u)表示以节点u为根的子树中节点总数。

d(u)表示用1 ~ size(u)给以u为根的子树编号的合法方案数,考虑下面几种情况:

①:  u是叶子节点,方案数为1.

②:  u的所有儿子节点都是叶子节点,那么所有儿子节点连续(假设儿子节点有S个),u只能放在所有儿子节点的前面或者最后面。所以方案数就是2(S!),因为儿子节点之间互不影响可以任意排列。

③:  u只有一个非叶儿子节点v。

方案数为:2 * d(v) * S!

首先子树v的排列方案有d(v)种,子树v的排列确定下来以后,而且v一定是在这个排列的某一端,由于所有儿子节点连续,所以这S个v的叶子兄弟必须紧挨着v,所以有S!种,此时只有u的位置没有确定好,u可以放在排列的开头或者末尾,所以答案最终要乘2.

④:  u有两个非叶子儿子节点v1, v2.

首先u的所有儿子节点是要连续的,所以v1, v2和他俩的叶子兄弟要在连续的一段;而且还要满足,v1这棵子树连续,v2这棵子树连续,所以v1和v2注定只能排在在u的儿子中的两端。

排列大概就是这样的,因为v1排在左端的方案数为d(v1) / 2,同样地v2排在右端的方案数为d(v2) / 2,叶子兄弟在v1和v2之间任意排列,u排在左右两端都行。

所以上图表示总的方案数为 d(v1) / 2 * d(v2) / 2 * S! * 2 = d(v1) * d(v2) / 2 * S!

不要急,还有一半情况没考虑到。就是v1子树排在右边,v2子树排在左边,所以上面的答案还要乘个2,得到 d(v1) * d(v2) * S!

⑤:  非叶子节点数多于两个,开头已经说过了,无解。

因为数据比较大,要手动扩栈然后用C++提交。

 #pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; typedef long long LL; const int maxn = + ;
const LL MOD = ; vector<int> G[maxn]; int sz[maxn];
LL d[maxn], fac[maxn]; void dfs(int u, int fa)
{
sz[u] = ;
LL T = ;
int c1 = , c2 = ;
for(int i = ; i < G[u].size(); i++)
{
int v = G[u][i];
if(v == fa) continue;
dfs(v, u);
sz[u] += sz[v]; if(d[v] == ) { d[u] = ; return ; } if(sz[v] > ) { c1++; T = (T * d[v]) % MOD; }
else c2++; if(c1 > ) { d[u] = ; return ; }
} if(sz[u] == ) { d[u] = ; return ; }
if(c1 < ) d[u] = (2LL * fac[c2] * T) % MOD;
else d[u] = (fac[c2] * T) % MOD;
} int main()
{
fac[] = ;
for(int i = ; i < maxn; i++) fac[i] = (fac[i - ] * i) % MOD; int T; scanf("%d", &T);
for(int kase = ; kase <= T; kase++)
{
int n; scanf("%d", &n);
for(int i = ; i <= n; i++) G[i].clear();
for(int i = ; i < n; i++)
{
int u, v; scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
} printf("Case #%d: ", kase); if(n == ) { puts(""); continue; } dfs(, );
printf("%I64d\n", d[]);
} return ;
}

代码君

HDU 5379 树形DP Mahjong tree的更多相关文章

  1. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  2. 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)

    题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...

  3. codevs 1380/HDU 1520 树形dp

    1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 回到问题 题目描述 Description Ural大学有N个职员 ...

  4. HDU 1520 树形dp裸题

    1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...

  5. HDU 1561 树形DP入门

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  6. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  7. HDU 1520 树形DP入门

    HDU 1520 [题目链接]HDU 1520 [题目类型]树形DP &题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知 ...

  8. HDU 5834 [树形dp]

    /* 题意:n个点组成的树,点和边都有权值,当第一次访问某个点的时候获得利益为点的权值 每次经过一条边,丢失利益为边的权值.问从第i个点出发,获得的利益最大是多少. 输入: 测试样例组数T n n个数 ...

  9. hdu 4267 树形DP

    思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零.那么对剩下的图就可以直接树形dp求解了. #include<iostream> #include<al ...

随机推荐

  1. Redis的数据类型(Strings、 hashes)

    字符串(Strings)类型及操作 字符串是Redis值的最基础的类型,一个key对应一个value,Redis字符串是二进制安全的,这意味着一个Redis字符串可以包含任何种类的数据,例如一个JPE ...

  2. 函数补充:动态参数,函数嵌套,global与nonlocal关键

    一丶动态参数 1.*args 位置参数,动态传参 def func(*food): print(food) print(func("米饭","馒头"," ...

  3. jsp-简单的猜数小游戏

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...

  4. ECSHOP 商品增加新字段的方法

    在ecshop二次开发工作中,经常碰到一些ECSHOP高级使用者问我,如何给商品增加一个新字段,来录入一些新的内容. 下面我们结合ecshop后台“商品编辑”.“商品录入”来谈谈如何给ecshop商品 ...

  5. filter和map的使 使得数组对象变数组

    let UnitList = this.paytypeData.filter( item => item.CheckBox === true ).map(axis => axis.Unit ...

  6. 在开发第一个Android应用之前需要知道的5件事:

    你能否详细讲述一下,在开发Android应用过程中每一阶段要用到的技能和编程语言? 建立一个Android应用程序可以归结为两个主要技能/语言:Java和Android系统.Java是Android的 ...

  7. SDUT 1309 不老的传说问题 (区间DP)

    题意: 有一个环形序列,n个数字表示一种颜色,要求将白板环刷成一模一样的环,限制是每次最多只能刷连续的K个位置,问最少需要刷几次? 思路: 跟2008长春那道painter string 差不多.只是 ...

  8. 洛谷 P2383 狗哥玩木棒

    题目背景 狗哥又趁着语文课干些无聊的事了... 题目描述 现给出一些木棒长度,那么狗哥能否用给出的木棒(木棒全用完)组成一个正方形呢? 输入输出格式 输入格式: 输入文件中的第一行是一个整数n表示测试 ...

  9. 程序员的智囊库系列之3--分布式文件系统(Distributed file systems)

    程序员的智囊库系列之3--分布式文件系统(Distributed file systems) 这是程序员的智囊库系列的第三篇文章.上一篇文章本来打算介绍几个搭建网站的框架,但由于这部分的内容较多,还需 ...

  10. DIV在另一个DIV里面垂直居中,水平居中

    HTML: <div class="parent"> <div class="children"> <div class=&quo ...