UVA11174村民排队问题
题意:
有n个人要排队,给你一些父子关系,要求儿子不能站在自己的父亲前面,问有多少种排队方式?
思路:
白书上的题目,首先我们可以把关系建成树,这样我们就有可能得到一个森林(或者是一课树),然后我们再虚拟出来一个点0连接所有森林的根节点,这样是为了保证是一棵树,然后题目就变成了给你一棵树,不改变关系,问这个树有多少种方式,这个还是排列组合问题,对于每一个根节点,有这样的性质
root[i] = f[1]*f[2]*..f[k] * (s[i]-1)!/s[1]!*s[2]!*..s[k]!
f[1]..f[k]表示的当前根节点连接的k个儿子为根节点的树的排列个数,s[i]表示的是以i为根节点的这棵树的所有节点个数,上面的式子可以理解成这样
f[1]*f[2]*..f[k] 所有儿子为根节点的排列个数
(s[i] - 1)! 表示的是以i为根的这棵树的所有节点数-1(不算跟所以-1)的排列方式
//s[1]!*s[2]!*..s[k]! 相当于全排列去掉重复部分,因为每一棵树已经*f[]了,不能在*了,不能再*那就可以理解成重复部分了,所以...,然后把每一个公式都化简,会发现分子剩1,分母剩s[i]了,(可以理解成分子的f[i]和分母的s[i]!约),这样最后剩下的是
((n+1)-1)/s1*s2*..sn;
最后的公式是
Ans = n!/(s1*s2*s3*s4...*sn) si是以i为根节点的子树的节点数
这样就可以了,然后这样会设计到一个问题,那就是大数相除取余的问题,我知道应该有至少两种方法解决这个问题,一个是逆元,另一个是a/b%c = a * pow(b ,c - 2) % c,这个不解释了,可以自己去网上找学习,哎!想起了亚洲赛那道排列组合题,当时在赛场上怎么也想不起来大数相除的转换了,sb了!
#include<stdio.h>
#include<string.h>
#define MOD 1000000007
#define N_node 40000 + 10
#define N_edge 40000 + 10
typedef struct
{
int to ,next;
}STAR;
STAR E[N_node];
long long sum[N_node];
long long jc[N_node];
int list[N_node] ,tot;
int du[N_node];
void add(int a ,int b)
{
E[++tot].to = b;
E[tot].next = list[a];
list[a] = tot;
}
int DFS(int now)
{
int s = 1;
for(int k = list[now] ;k ;k = E[k].next)
{
s += DFS(E[k].to);
}
sum[now] = s;
return s;
}
long long Pow(long long a ,long long b)
{
long long c = 1;
while(b)
{
if(b & 1) c *= a;
b >>= 1;
a *= a;
a = a % MOD;
c = c % MOD;
}
return c;
}
void DB()
{
long long now = 1;
for(long long i = 1 ;i <= 40000 ;i ++)
{
now = now * i % MOD;
jc[i] = now;
}
}
int main ()
{
int n ,m ,i ,a ,b ,t;
DB();
scanf("%d" ,&t);
while(t--)
{
scanf("%d %d" ,&n ,&m);
memset(list ,0 ,sizeof(list)) ,tot = 1;
memset(du ,0 ,sizeof(du));
for(i = 1 ;i <= m ;i ++)
{
scanf("%d %d" ,&a ,&b);
add(b ,a);
du[a] ++;
}
for(i = 1 ;i <= n ;i ++)
if(!du[i]) add(0 ,i);
memset(sum ,0 ,sizeof(sum));
DFS(0);
long long Ans = jc[n];
for(i = 1 ;i <= n ;i ++)
{
Ans = Ans * Pow(sum[i] ,MOD - 2) % MOD;
}
printf("%lld\n" ,Ans);
}
return 0;
}
UVA11174村民排队问题的更多相关文章
- [uva11174]村民排队 递推+组合数+线性求逆元
n(n<=40000)个村民排成一列,每个人不能排在自己父亲的前面,有些人的父亲不一定在.问有多少种方案. 父子关系组成一个森林,加一个虚拟根rt,转化成一棵树. 假设f[i]表示以i为根的子树 ...
- acdream 1683 村民的怪癖(KMP,经典变形)
Problem Description 娜娜费劲九牛二虎之力终于把糖果吃完了(说好的吃不完呢?骗人,口亨~),于是,缘溪行,忘路之远近.忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷,娜娜甚异之 ...
- POJ 2828 Buy Tickets(排队问题,线段树应用)
POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意: 排队买票时候插队. 给出一些数对,分别代表某个人的想要插入的位 ...
- D - 娜娜梦游仙境系列——村民的怪癖
D - 娜娜梦游仙境系列——村民的怪癖 Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Othe ...
- Python开发——排队问题随机模拟分析
案例:主要是基于"蒙特卡罗思想",求解排队等待时间问题 场景:厕所排队问题 1.两场电影结束时间相隔较长,互不影响: 2.每场电影结束之后会有20个人想上厕所: 3.这20个人会在 ...
- 银行排队问题之单队列多窗口加VIP服务(30 分)
银行排队问题之单队列多窗口加VIP服务(30 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选 ...
- PTA 银行排队问题之单队列多窗口服务(25 分)
银行排队问题之单队列多窗口服务(25 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假 ...
- POJ2182(排队问题)
Lost Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10695 Accepted: 6865 Descri ...
- codevs——2956 排队问题
2956 排队问题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有N个学生去食堂,可教官规定:必须2人或3 ...
随机推荐
- Python爬虫系统化学习(5)
Python爬虫系统化学习(5) 多线程爬虫,在之前的网络编程中,我学习过多线程socket进行单服务器对多客户端的连接,通过使用多线程编程,可以大大提升爬虫的效率. Python多线程爬虫主要由三部 ...
- 漏洞复现-2.x rce-Thinkphp远程命令执行
0x00实验环境 攻击机:win10 靶机:Ubuntu18 (docker搭建的vulhub靶场) 0x01影响版本 影响Thinkphp 2.x的版本 0x02实验目的 学 ...
- Maven安装本地依赖包
前提已安装maven并且配置了环境变量1.进入jar包所在的目录,打开cmd2.了解包的groupId.artifactId.version2.输入命令(依赖sdk为例)---maven命令mvn i ...
- Linux tar 使用笔记
常用语法 打包和压缩包 仅打包不压缩:tar -cvf usr.tar /usr 将 /usr 目录打包为 usr.tar 打包并以 gz 格式压缩:tar -czvf usr.tar.gz /usr ...
- 【LeetCode】2020-03 每日一题
121. 买卖股票的最佳时机(简单) [分类]:模拟.思维 [题解]:可以用O(n)的复杂度完成,只需要在遍历的时候记录到当前位置为止买入股票的最小价格minn,再维护一个当前卖出股票价(a-minn ...
- P1028_数的计算(JAVA语言)
题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(0n≤1000),然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自然数,但该自然数不能 ...
- python3 byte,int,str转换
1 # bytes 与 int 2 b=b'\x01\x02' 3 num=int.from_bytes(b,'little') 4 print('bytes转int:',num) 5 6 b1=nu ...
- redis数据库如何批量删除键和设置过期时间?
我们可以借助Linux中的xargs,在终端中执行命令来实现这两个功能. 一.批量删除键 批量删除以"key"开头key的方法,需要借助Linux中的xargs,在终端中执行以下命 ...
- java例题_16 九九乘法表
1 /*题目:输出 9*9 口诀. 2 程序分析:分行与列考虑,共 9 行 9 列,i 控制行,j 控制列. 3 */ 4 5 /*分析 6 * 用两侧for循环,外层循环还要控制换行 7 * 换行时 ...
- 系统编程-信号-总体概述和signal基本使用
信号章节 -- 信号章节总体概要 信号基本概念 信号是异步事件,发送信号的线程可以继续向下执行而不阻塞. 信号无优先级. 1到31号信号是非实时信号,发送的信号可能会丢失,不支持信号排队. 31号信号 ...