HDU 5379 Mahjong tree(树的遍历&组合数学)
2015-08-12 09:07
369 查看
本文纯属原创,转载请注明出处。谢谢。http://blog.csdn.net/zip_fan
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5379
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
Little sun is an artist. Today he is playing mahjong alone. He suddenly feels that the tree in the yard doesn't look good. So he wants to decorate the tree.(The tree has n vertexs, indexed from 1 to n.)
Thought for a long time, finally he decides to use the mahjong to decorate the tree.
His mahjong is strange because all of the mahjong tiles had a distinct index.(Little sun has only n mahjong tiles, and the mahjong tiles indexed from 1 to n.)
He put the mahjong tiles on the vertexs of the tree.
As is known to all, little sun is an artist. So he want to decorate the tree as beautiful as possible.
His decoration rules are as follows:
(1)Place exact one mahjong tile on each vertex.
(2)The mahjong tiles' index must be continues which are placed on the son vertexs of a vertex.
(3)The mahjong tiles' index must be continues which are placed on the vertexs of any subtrees.
Now he want to know that he can obtain how many different beautiful mahjong tree using these rules, because of the answer can be very large, you need output the answer modulo 1e9 + 7.
Input
The first line of the input is a single integer T, indicates the number of test cases.
For each test case, the first line contains an integers n. (1 <= n <= 100000)
And the next n - 1 lines, each line contains two integers ui and vi, which describes an edge of the tree, and vertex 1 is the root of the tree.
Output
For each test case, output one line. The output format is "Case #x: ans"(without quotes), x is the case number, starting from 1.
Sample Input
2
9
2 1
3 1
4 3
5 3
6 2
7 4
8 7
9 3
8
2 1
3 1
4 3
5 1
6 4
7 5
8 4
Sample Output
Case #1: 32
Case #2: 16
题意:在一颗树上有n个节点,现在要把他们进行1-n编号。要保证1、兄弟节点之间号是连续的,2、每棵子树号自身是连续的,求一共有多少种可能。
其实非常简单,首先兄弟节点之间号是连续的,而且子树号是连续的,那么互为兄弟节点的那些点中,至多有2个节点有儿子节点,否则不可能满足上述条件。
只要明白了这一点,直接遍历树,统计即可。
但是题目有一个非常大的神坑点:给边的时候是随意的,所以必须先双向建图,然后从根节点开始遍历一遍,把多余的边删掉。(比赛的时候被坑了好久)
当然hdu的栈深度就不吐槽了,手动开栈,c++提交。
下面上代码。
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5379
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
Little sun is an artist. Today he is playing mahjong alone. He suddenly feels that the tree in the yard doesn't look good. So he wants to decorate the tree.(The tree has n vertexs, indexed from 1 to n.)
Thought for a long time, finally he decides to use the mahjong to decorate the tree.
His mahjong is strange because all of the mahjong tiles had a distinct index.(Little sun has only n mahjong tiles, and the mahjong tiles indexed from 1 to n.)
He put the mahjong tiles on the vertexs of the tree.
As is known to all, little sun is an artist. So he want to decorate the tree as beautiful as possible.
His decoration rules are as follows:
(1)Place exact one mahjong tile on each vertex.
(2)The mahjong tiles' index must be continues which are placed on the son vertexs of a vertex.
(3)The mahjong tiles' index must be continues which are placed on the vertexs of any subtrees.
Now he want to know that he can obtain how many different beautiful mahjong tree using these rules, because of the answer can be very large, you need output the answer modulo 1e9 + 7.
Input
The first line of the input is a single integer T, indicates the number of test cases.
For each test case, the first line contains an integers n. (1 <= n <= 100000)
And the next n - 1 lines, each line contains two integers ui and vi, which describes an edge of the tree, and vertex 1 is the root of the tree.
Output
For each test case, output one line. The output format is "Case #x: ans"(without quotes), x is the case number, starting from 1.
Sample Input
2
9
2 1
3 1
4 3
5 3
6 2
7 4
8 7
9 3
8
2 1
3 1
4 3
5 1
6 4
7 5
8 4
Sample Output
Case #1: 32
Case #2: 16
题意:在一颗树上有n个节点,现在要把他们进行1-n编号。要保证1、兄弟节点之间号是连续的,2、每棵子树号自身是连续的,求一共有多少种可能。
其实非常简单,首先兄弟节点之间号是连续的,而且子树号是连续的,那么互为兄弟节点的那些点中,至多有2个节点有儿子节点,否则不可能满足上述条件。
只要明白了这一点,直接遍历树,统计即可。
但是题目有一个非常大的神坑点:给边的时候是随意的,所以必须先双向建图,然后从根节点开始遍历一遍,把多余的边删掉。(比赛的时候被坑了好久)
当然hdu的栈深度就不吐槽了,手动开栈,c++提交。
下面上代码。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <map> #include <queue> #include <vector> #include <iostream> #include <algorithm> #define moo 1000000007//10^9+7 #define PI acos(-1.0) #define eps 1e-5 #pragma comment (linker,"/STACK:102400000,102400000") using namespace std; long long jie[100000+100];//存阶乘,即全排列情况 vector<int>tre[100000+100];//存点i能到的点,相当于邻接表建图。 int vis[100000+100];//存第i个点的访问情况 void init() { jie[0]=1; for(int i=1;i<=100000;i++) { jie[i]=jie[i-1]*i; jie[i]%=moo; } }//n个无子节点的兄弟节点可以有n!种排列 void dfs1(int num)//先遍历一遍树,将多余的边删除 { vis[num]=1; int nn=tre[num].size(); int now=0; while(now<nn) { if(vis[tre[num][now]]==1) { tre[num].erase(tre[num].begin()+now); nn--; continue; } dfs1(tre[num][now]); now++; } } long long dfs(int num,int has)//统计num节点的情况,has代表num是否有兄弟节点 { if(tre[num].size()==0)//如果num没有子节点,直接return 1,表示只有1种排列情况 return 1; long long ans=1; int num1=0;//存num点的子节点中无子节点的节点个数 int num2=0;//存num点的子节点中有子节点的节点个数 int nn=tre[num].size(); for(int i=0;i<nn;i++) { if(tre[tre[num][i]].size()==0) num1++; else num2++; } if(num2>2) return 0;//如果有超过2个点有子节点,那么一定无法满足条件,return 0 if(has==0)//如果num点没有兄弟节点,那么num点可以在子节点的最左或者最右,即2种选择 ans*=2; ans*=jie[num1];//num的子节点中无子节点的节点可以组成全排列 ans%=moo; if(num2==0)//如果没有有子节点的节点,那么该点统计完毕 return ans; if(tre[num].size()!=1)//如果不止有一个有子节点的子节点,那么该子节点可以在最左或最右 ans*=2; int go; if(tre[num].size()==1)//判断其子节点是否有兄弟节点,为其子节点的统计做准备 go=0; else go=1; for(int i=0;i<nn;i++) { if(tre[tre[num][i]].size()!=0) { long long la=ans; ans*=dfs(tre[num][i],go);//如果该点有子节点,继续统计 ans%=moo; } } return ans%moo; } int main() { int T; cin>>T; int dd=T; init(); while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) tre[i].clear(); memset(vis,0,sizeof(vis)); for(int i=1;i<=n-1;i++) { int x,y; scanf("%d%d",&x,&y); tre[y].push_back(x); tre[x].push_back(y); } dfs1(1); printf("Case #%d: %I64d\n",dd-T,dfs(1,0)); } return 0; }
相关文章推荐
- Win2003利用dfs(分布式文件系统)在负载均衡下的文件同步配置方案
- win2003分布式文件系统(dfs)配置方法[图文详解]
- win2003分布式文件系统及其部署 图文教程
- 简单的四则运算
- 数的奇偶性
- Hadoop2.6+jdk8的安装部署(1)——使用jar包安装部署【详细】
- Hadoop FS Shell
- DFS使用方法总结
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- FastDFS注意事项
- 无忧技术带您预览DFS(分布式文件系统)管理控制台
- 矩阵的乘法操作
- C 语言实现迷宫 DFS算法
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置