题意:

     有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村民排队问题的更多相关文章

  1. [uva11174]村民排队 递推+组合数+线性求逆元

    n(n<=40000)个村民排成一列,每个人不能排在自己父亲的前面,有些人的父亲不一定在.问有多少种方案. 父子关系组成一个森林,加一个虚拟根rt,转化成一棵树. 假设f[i]表示以i为根的子树 ...

  2. acdream 1683 村民的怪癖(KMP,经典变形)

    Problem Description 娜娜费劲九牛二虎之力终于把糖果吃完了(说好的吃不完呢?骗人,口亨~),于是,缘溪行,忘路之远近.忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷,娜娜甚异之 ...

  3. POJ 2828 Buy Tickets(排队问题,线段树应用)

    POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意:  排队买票时候插队.  给出一些数对,分别代表某个人的想要插入的位 ...

  4. D - 娜娜梦游仙境系列——村民的怪癖

    D - 娜娜梦游仙境系列——村民的怪癖 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Othe ...

  5. Python开发——排队问题随机模拟分析

    案例:主要是基于"蒙特卡罗思想",求解排队等待时间问题 场景:厕所排队问题 1.两场电影结束时间相隔较长,互不影响: 2.每场电影结束之后会有20个人想上厕所: 3.这20个人会在 ...

  6. 银行排队问题之单队列多窗口加VIP服务(30 分)

    银行排队问题之单队列多窗口加VIP服务(30 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选 ...

  7. PTA 银行排队问题之单队列多窗口服务(25 分)

    银行排队问题之单队列多窗口服务(25 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假 ...

  8. POJ2182(排队问题)

    Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10695   Accepted: 6865 Descri ...

  9. codevs——2956 排队问题

    2956 排队问题  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 有N个学生去食堂,可教官规定:必须2人或3 ...

随机推荐

  1. 2020年12月-第02阶段-前端基础-CSS Day05

    CSS Day05 1. 学成在线页面制作 理解 能够说写单页面我们基本的流程 能说出常见的css初始化语句 能说出我们CSS属性书写顺序 应用 能利用ps切图 能引入外部样式表 能把psd文件转换为 ...

  2. 漫漫Java路1—基础知识3—数据类型和变量作用域以及常量

    强类型语言 所有变量定义后才能使用,区别于js等弱类型语言 数据类型分类 基本类型(primitive type) 引用类型(reference type) 整数类 byte:占1字节 short:占 ...

  3. LNMP配置——Nginx配置 ——域名重定向

    一.配置 #vi /usr/local/nginx/conf/vhost/test.com.conf 写入: server { listen 80; server_name test.com test ...

  4. HDU_6590 Code 【凸包】

    一.题目 Code 二.分析 题目描述了一大堆东西,就是想问二维空间里,能不能确定$d  w_1   w_2$使得函数满足$f(x_1,x_2) = y$,并且$sign(x)$函数是一个信号函数,只 ...

  5. Nodejs学习笔记(5) 文件上传系统实例

    目录 2018.8.4更新:  MySQL可以存放几乎任何类型的数据(图片.文档.压缩包等),但这不是最好的解决方案,正常情况下都是在数据库中存放文件路径,图片.音乐.视频.压缩包.文档等文件存放在硬 ...

  6. reverseLinkedList(翻转链表)

    ReverseLinkedList(翻转链表) 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.非连续.非顺序指的是,通过指针把一组零散的内存块串 ...

  7. Linux内核模块驱动加载与dmesg调试

    因为近期用到了Linux内核的相关知识,下面随笔将给出内核模块的编写记录,供大家参考. 1.运行环境 Ubuntu 版本:20.04 Linux内核版本:5.4.0-42-generic gcc版本: ...

  8. linux中的gtk 编程的页面切换

    在我们使用gtk这个工具时,有时想在同一个窗口中,根据选择来显示不同的操作菜单,这篇博文主要是解决此类问题 //创建窗口 GtkWidget *CreateMenuMain() { GtkWidget ...

  9. 制作API离线chm帮助文件教程

    当我们开发好一个通信库的时候,我们希望给这个通信库配备一个帮助文档,最好的方式,就是有一个离线的chm版本的API文档,这样别人在使用的时候,就可以清楚看到命名空间.类的结构,同时也能看到每个方法和属 ...

  10. 全量同步Elasticsearch方案之Canal

    一.前言 Canal 是阿里的一款开源项目,纯 Java 开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了 MySQL(也支持 mariaDB). Canal 除了支持 b ...