题意:在一棵有n个节点的树上放编号从1到n的麻将,要求每个点的儿子节点之间的编号连续,每棵子树内的编号连续。

解法:手推一组样例之后就可以得到如下结论然后从根节点一边讨论一边搜就好了。

当一个节点只有一个儿子的时候,如果儿子是叶子节点则只有一种放法,如果儿子不是叶子节点则有两种放法。

当一个节点有两个儿子的时候,一定有两种放法。

当一个儿子有三个儿子及以上的时候,假设有k个儿子,如果非叶子节点m的个数为0则有k!种放法,如果m为1,则有2 × (k - 1)!种放法,如果m为2,则有2 × (k - 2)!种放法,如果m > 2则不存在合法情况。

将所有情况相乘即为答案。

代码:

代码是队友写的……这么鬼畜的变量名才不是我起的呢233

哦对了……要手动扩栈不然会RE

#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <limits.h>
using namespace std;
typedef long long LL;
#define MAXN 100010//1e5
const LL mod = (LL)1e9 + 7;
int t, n, cas;
vector<int> edge[MAXN];
bool vis[MAXN];
LL ans;
LL A[MAXN];
void init() {
for(int i = 0; i <= n; i++) {
edge[i].clear();
}
edge[0].push_back(1);
edge[1].push_back(0);
memset(vis, false, sizeof vis);
vis[0] = true;
ans = 1LL;
}
void DFS(int u) {
int len = edge[u].size();
if((len == 1 && u != 0) || ans == 0LL) return ;
if(len - 1 == 1 || u == 0) {
for(int i = 0; i < len; i++) {
int v = edge[u][i];
if(!vis[v]) {
if(edge[v].size() - 1 > 0) {
ans = (ans * 2LL) % mod;
vis[v] = true;
if(ans == 0LL) return;
DFS(v);
}
}
}
} else if(len - 1 == 2) {
ans = (ans * 2LL) % mod;
for(int i = 0; i < len; i++) {
int v = edge[u][i];
if(vis[v]) continue;
vis[v] = true;
if(ans == 0LL) return;
DFS(v);
}
} else if(len - 1 >= 3) {
vector<int> son;
int cnt = 0;
int dayu0 = 0;
for(int i = 0; i < len; i++) {
int v = edge[u][i];
if(vis[v]) continue;
son.push_back(v);
if(edge[v].size() - 1 > 0) dayu0++;
}
cnt = son.size();
if(dayu0 == 0) {
ans = (ans * A[cnt]) % mod;
} else if(dayu0 == 1) {
ans = (ans * 2LL) % mod;
ans = (ans * A[cnt - 1]) % mod;
} else if(dayu0 == 2) {
ans = (ans * 2LL) % mod;
ans = (ans * A[cnt - 2]) % mod;
} else {
ans = 0LL; return ;
}
for(int i = 0; i < cnt; i++) {
int v = son[i];
vis[v] = true;
if(ans == 0LL) return ;
DFS(v);
}
}
}
int main() {
scanf("%d", &t);
A[1] = 1LL;
for(LL i = 2; i <= 100000LL; i++) {
A[i] = A[i - 1] * i % mod;
}
while(t--) {
scanf("%d", &n);
init();
int u, v;
for(int i = 0; i < n - 1; i++) {
scanf("%d%d", &u, &v);
edge[u].push_back(v);
edge[v].push_back(u);
}
DFS(0);
printf("Case #%d: %I64d\n", ++cas, ans);
}
return 0;
}

  

HDU 5379 Mahjong tree的更多相关文章

  1. Hdu 5379 Mahjong tree (dfs + 组合数)

    题目链接: Hdu 5379 Mahjong tree 题目描述: 给出一个有n个节点的树,以节点1为根节点.问在满足兄弟节点连续 以及 子树包含节点连续 的条件下,有多少种编号方案给树上的n个点编号 ...

  2. HDU 5379 Mahjong tree(dfs)

    题目链接:pid=5379">http://acm.hdu.edu.cn/showproblem.php? pid=5379 Problem Description Little su ...

  3. HDU 5379 Mahjong tree(树的遍历&amp;组合数学)

    本文纯属原创,转载请注明出处.谢谢. http://blog.csdn.net/zip_fan 题目传送门:http://acm.hdu.edu.cn/showproblem.php? pid=537 ...

  4. HDU 5379——Mahjong tree——————【搜索】

    Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  5. 2015 Multi-University Training Contest 7 hdu 5379 Mahjong tree

    Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  6. 2015多校第7场 HDU 5379 Mahjong tree 构造,DFS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5379 题意:一颗n个节点n-1条边的树,现在要给每个节点标号(1~n),要求:(1)每一层的兄弟节点的 ...

  7. HDU 5379 Mahjong tree dfs+组合数学

    题意:给你一棵树来分配号码,要求是兄弟节点连续并且每一棵子树连续. 思路:因为要求兄弟和子树都是连续的,所以自己打下草稿就可以发现如果一个节点有3个或3个以上的非叶子结点,那么就无论如何也不能达到目的 ...

  8. Mahjong tree (hdu 5379 dfs)

    Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  9. 【HDOJ 5379】 Mahjong tree

    [HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共同拥有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根 ...

随机推荐

  1. 【hadoop2.6.0】MapReduce原理

    看了几篇博文,感觉还是云里雾里的. http://blog.csdn.net/opennaive/article/details/7514146 http://www.aboutyun.com/thr ...

  2. docker: "build" requires 1 argument. See 'docker build --help'.

    http://bbs.csdn.net/topics/391040030 docker build  --tag="ouruser/sinatra:v3" -<Dockerf ...

  3. ibaits与spring整合的心得

    Ibatis2.3与spring3.0整合,其要明确一下,Ibatis与Hibernate一样都是dao层链接数据库用的框架.它是一个轻量级的orm框架,比Hibernate更加灵活. sqlMapC ...

  4. Visual Studio 2010快捷键大全

    http://www.cnblogs.com/zhuiyi/archive/2011/10/26/2224941.html [窗口快捷键]Ctrl+W,W: 浏览器窗口 Ctrl+W,S: 解决方案管 ...

  5. HTML5入门5---HTML5控件元素

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. VS2010/MFC编程入门教程之目录和总结

    鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...

  7. SVN 目录结构

    Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-ta ...

  8. android移植

    root@phone-desktop:/opt/4418-source/android4.4.2_r1# ./device/nexell/tools/build.sh -b drone2 -t u-b ...

  9. Oracle 数据集成的实际解决方案

    就针对市场与企业的发展的需求,Oracle公司提供了一个相对统一的关于企业级的实时数据解决方案,即Oracle数据集成的解决方案.以下的文章主要是对其解决方案的具体描述,望你会有所收获. Oracle ...

  10. CentOS 6.5系统使用yum方式安装LAMP环境和phpMyAdmin详细过程

    介绍如何在CentOs6.2下面使用YUM配置安装LAMP环境,一些兄弟也很喜欢使用编译的安装方法,个人觉得如果不是对服务器做定制,用yum安装稳定简单,何必去download&make&am ...