HDU 5379 树形DP Mahjong tree
任意一棵子树上节点的编号连续,每个节点的所有二字节点连续,求编号方案的总数。
稍微分析一下可知
- 每个节点的非叶子节点个数不能多于两个,否则这个子树无解,从而整棵树都无解。
- 每棵子树将所有节点按照编号从小到大排序,根节点要么在最左端,要么在最右端,而且这两种情况相等。(后面会有具体分析)
设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的更多相关文章
- hdu 4123 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)
题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...
- codevs 1380/HDU 1520 树形dp
1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 回到问题 题目描述 Description Ural大学有N个职员 ...
- HDU 1520 树形dp裸题
1.HDU 1520 Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...
- HDU 1561 树形DP入门
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU 2196树形DP(2个方向)
HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...
- HDU 1520 树形DP入门
HDU 1520 [题目链接]HDU 1520 [题目类型]树形DP &题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知 ...
- HDU 5834 [树形dp]
/* 题意:n个点组成的树,点和边都有权值,当第一次访问某个点的时候获得利益为点的权值 每次经过一条边,丢失利益为边的权值.问从第i个点出发,获得的利益最大是多少. 输入: 测试样例组数T n n个数 ...
- hdu 4267 树形DP
思路:先dfs一下,找出1,n间的路径长度和价值,回溯时将该路径长度和价值清零.那么对剩下的图就可以直接树形dp求解了. #include<iostream> #include<al ...
随机推荐
- Elasticsearch优化
2.out of memory错误 因为默认情况下es对字段数据缓存(Field Data Cache)大小是无限制的,查询时会把字段值放到内存,特别是facet查询,对内存要求非常高,它会把结果都放 ...
- 报错:Could not reserve enough space for object heap error
windows命令行运行某个命令时出现: 解决办法: 设置开始->控制面板->系统和安全->系统->高级系统设置->环境变量->系统变量->新建: 变量名: ...
- js中Object.defineProperty()和defineProperties()
在介绍js中Object.defineProperty()和defineProperties()之前,我们了解下js中对象两种属性的类型:数据属性和访问器属性. 数据属性 数据属性包含一个数据的位置, ...
- 终于有人把P2P、P2C、O2O、B2C、B2B、C2C的区别讲透了!还有许多其它类别的类型分享
平时在看招聘时,经常看到我们是什么B2C电子商务网站,但是一直不知是啥意思,今天在WEB开发者上面看到这篇文章,就是知道了个所以然,以记录分享. P2P.P2C .O2O .B2C.B2B. C2C, ...
- webm视频转换 其他视频格式转换为webm格式
将其他视频格式转换为webm格式 https://files.cnblogs.com/files/bubuchu/html5videoshipingeshizhuanhuanqi.zip
- C++析构函数造成Debug Assertion Failed的问题
昨天写了两个程序,均出现了析构函数造成Debug Assertion Failed的问题,由于是初学c++怎么想也想不通问题出在哪里.今天早上经人指点终于明白问题所在了.下面贴出代码和问题解析:(以下 ...
- Python3+Selenium3+webdriver学习笔记10(元素属性、页面源码)
#!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记10(元素属性.页面源码)'''from selenium i ...
- ssh连接github连不上
连接github报端口22连接不上: 输入命令展示出ssh_config内容后: vim /etc/ssh/ssh_config 或者使用open /etc/ssh/ssh_config命令在文本编辑 ...
- Spring 和 Mybatis 整合
Spring 和 Mybatis 整合 Spring本身的Config文件: 在IDEA下面配置好文件后, 在WEB-INF下面有三个配置文件分别是web.xml, applicationContex ...
- ubuntu开放端口
1.安装iptables(一般情况,ubuntu安装好的时候,iptables会被安装上),使用以下命令: $apt-get update $apt-get install iptables 2.安装 ...