Hdu 5379 Mahjong tree (dfs + 组合数)
2024-09-30 16:22:13
题目链接:
题目描述:
给出一个有n个节点的树,以节点1为根节点。问在满足兄弟节点连续 以及 子树包含节点连续 的条件下,有多少种编号方案给树上的n个点编号?
解题思路:
对于一个节点来讲,非叶子儿子节点最多有两个才能满足要求,否则满足子树节点连续的话就无法满足兄弟节点连续。然后有dfs计算每棵子树的贡献值,每棵子树的子节点可以分为叶子节点X和非叶子节点Y,叶子节点可以分配到一组连续的编号,非叶子节点只能分配到兄弟节点中最大或者最小编号两种情况,叶子节点的贡献值为X!。然后dfs跑一下就ok咯。
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment (linker, "/STACK:1024000000,1024000000")
using namespace std; const int maxn = ;
const int mod = (1e9 + );
typedef long long LL;
struct node
{
int to, next;
}edge[maxn*];
int head[][maxn], vis[maxn], tot, flag;
LL res; void Add (int from, int to)
{
edge[tot].to = to;
edge[tot].next = head[][from];
head[][from] = tot ++;
head[][from] ++;
} void dfs (int u)
{
int k, cnt;
k = cnt = ;
vis[u] = ;
for (int i=head[][u]; i!=-; i=edge[i].next)
{ int v = edge[i].to;
if (vis[v])
continue;
if (!vis[v] && head[][v]==)
cnt ++;
else
dfs (v);
k ++;
}
if (k - cnt > )
{
res = ;
return;
}
if (k != cnt)
res = (res * ) % mod;
while (cnt)
{
res = (res * cnt) % mod;
cnt --;
}
}
int main ()
{
int t, n, l = ;
scanf ("%d", &t); while (t --)
{
scanf ("%d", &n);
memset (head[], -, sizeof(head[]));
memset (head[], , sizeof(head[]));
memset (vis, , sizeof(vis));
tot = flag = ; for (int i=; i<n; i++)
{
int u, v;
scanf ("%d %d", &u, &v);
Add (u, v);
Add (v, u);
}
res = ;
dfs ();
printf ("Case #%d: %lld\n", ++l, n==?:res);
}
return ;
}
最新文章
- [书目20160624]Android应用开发从入门到精通
- Android成长日记-Fragment的生命周期与Activity通信
- Linux内核中大小端判定宏
- iOS runloop 资源汇总-b
- C++学习(五)
- OpenCV(2)-Mat数据结构及访问Mat中像素
- 数据结构《17》---- 自己主动补齐之《二》----Ternary Search Tree
- 在CentOS下安装crontab服务
- 原生js触碰到底部触发函数;
- Haproxy官方文档翻译(第三章)全局参数(1) 附英文原文
- cookie和session的区别及在Django中应用
- Y7000安装驱动显卡问题
- 【XSY2472】string KMP 期望DP
- Swift Write to file 到电脑桌面
- yii2快速導出phpexcel
- sxstrace启动.bat
- 11g新特性 -- Virtual Private Catalogs
- Oracle查询行对应block_id,file_id
- sql server的缺陷 将截断字符串或二进制数据 哪个字段
- TypeScript开发环境搭建(Visual studio code)