题意:在一棵有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. 自定义nagios check_load告警阀值

    自定义nagios  check_load告警阀值 日期:2012-01-11 来源: heipark 分享至: - 默认check_load配置 define service{ use generi ...

  2. Lua print on the same line

    In Pascal, I have write and writeln. Apparently Lua's print is similar to writeln of Pascal. Do we h ...

  3. Codeforces400D Dima and Bacteria

    题意:给你一个无向有权的图,图上的点被分成了几类,对于同类的点你需要判断它们之间相互的最短距离是不是0.满足这个条件之后要输出的是类与类之间的最短距离的矩阵.点给到10^5这么多,判断同类的点显然不能 ...

  4. [转]剖析ASP.Net MVC Application

    http://www.cnblogs.com/errorif/archive/2009/02/13/1389927.html 为了完全了解Asp.net MVC是怎样工作的,我将从零开始创建一个MVC ...

  5. C Primer Plus之C预处理器和C库

    编译程序前,先由预处理器检查程序(因此称为预处理器).根据程序中使用的预处理器指令,预处理器用符号缩略语所代表的内容替换程序中的缩略语. 预处理器不能理解C,它一般是接受一些文件并将其转换成其他文本. ...

  6. aircrack-ng 字典破解WPA / WPA2

    1. 安装 首先安装两个扩展sudo apt-get install build-essentialsudo apt-get install libssl-dev 然后到http://download ...

  7. *[hackerrank]Algorithmic Crush

    https://www.hackerrank.com/contests/w4/challenges/crush 第一眼觉得要用线段树,但据说会超时.其实这个可以通过生成pair排序来做. #inclu ...

  8. dubbo与zookeeper安装手册

    原文 示例提供者安装 (+) (#) 安装: wget http://code.alibabatech.com/mvn/releases/com/alibaba/dubbo-demo-provider ...

  9. React用JS 模拟动画介绍

    一. <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF ...

  10. 网上图书商城项目学习笔记-012BOOK模块查询2

    一.分析 > 按图名查询(模糊)(分页)> 按作者查询(分页)> 按出版社查询(分页)> 按id查询> 多条件组合查询(分页) 二.代码 1.view层 (1)gj.js ...