Description

「恒逸,你相信灵魂的存在吗?」

郭恒逸和姚枫茜漫步在枫音乡的街道上。望着漫天飞舞的红枫,枫茜突然问出这样一个问题。 
「相信吧。不然我们是什么,一团肉吗?要不是有灵魂……我们也不可能再见到你姐姐吧。」 
恒逸给出了一个略微无厘头的回答。枫茜听后笑了笑。
「那你仔细观察过枫叶吗?」 
说罢,枫茜伸手,接住了一片飘落的枫叶。 
「其实每一片枫叶都是有灵魂的。你看,枫叶上不是有这么多脉络吗?我听说,枫叶上有一些特殊的位置,就和人的穴位一样。脉络都是连接在这些穴位之间的。枫树的灵魂流过每片枫叶的根部,沿着这些脉络,慢慢漫进穴位,沁入整片枫叶。也是因为这个原因,脉络才都是单向的,灵魂可不能倒着溜回来呢。」 
恒逸似懂非懂地点了点头。枫茜接着说了下去。 
「正是因为有了灵魂,每片枫叶才会与众不同。也正是因为有了灵魂,每片枫叶也都神似其源本的枫树,就连脉络也形成了一棵树的样子。但如果仔细看的话,会发现,在脉络树之外,还存在其它的非常细的脉络。虽然这些脉络并不在树上,但他们的方向也同样顺着灵魂流淌的方向,绝不会出现可能使灵魂倒流的回路。」  
恒逸好像突然想到了什么。 
「那这些脉络岂不是可以取代已有的脉络,出现在脉络树上?」 
枫茜闭上了眼睛。 
「是啊,就是这样。脉络树并不是唯一的。只要有一些微小的偏差,脉络树就可能差之万里,哪怕是在这同一片枫叶上。就像我们的故事,结局也不是唯一的。只要改变一个小小的选项,故事流程可能就会被彻底扭转。」 
「真是深奥啊……」 
恒逸盯着这片红枫,若有所思地说。枫茜继续说道。 
「还不止如此呢。所有的脉络都不会永恒存在,也不会永恒消失。不管是脉络树上的脉络,还是之外的细小脉络,都是如此。存在的脉络可能断开消失,消失的脉络也可能再次连接。万物皆处在永恒的变化之中,人与人之间的羁绊也是。或许有一天,我们与大家的羁绊也会如同脉络一样,被无情地斩断。或许我们也终将成为“枫音乡的过客”。或许这一切都会是必然,是枫树的灵魂所决定的……」 
枫茜的眼角泛起了几滴晶莹剔透的泪珠。恒逸看着这样的枫茜,将她抱入怀中。  
「别这样想,枫茜。就算脉络断开,也有可能还会有新的脉络树,也还会与枫树的根相连。这样的话,我们的羁绊仍然存在,只是稍微绕了一些远路而已。无论如何,我都不会离开你的。因为你是我穷尽一生所寻找的,我的真恋啊!」 
两人的目光对上了。枫茜幸福地笑了,把头埋进了恒逸的怀抱。从远方山上的枫林中,传来了枫的声音。 
【问题描述】 
不妨假设枫叶上有 n个穴位,穴位的编号为 1 ~  n。有若干条有向的脉络连接
着这些穴位。穴位和脉络组成一个有向无环图——称之为脉络图(例如图 1),穴
位的编号使得穴位 1 没有从其他穴位连向它的脉络,即穴位 1 只有连出去的脉络;
由上面的故事可知,这个有向无环图存在一个树形子图,它是以穴位 1为根的包含
全部n个穴位的一棵树——称之为脉络树(例如图 2和图 3给出的树都是图1给出
的脉络图的子图);值得注意的是,脉络图中的脉络树方案可能有多种可能性,例
如图2和图 3就是图 1给出的脉络图的两个脉络树方案。 
       
脉络树的形式化定义为:以穴位 r 为根的脉络树由枫叶上全部 n个穴位以及 n-  1 条脉络组成,脉络树里没有环,亦不存在从一个穴位连向自身的脉络,且对于枫叶上的每个穴位 s,都存在一条唯一的包含于脉络树内的脉络路径,使得从穴位r 出发沿着这条路径可以到达穴位 s。
现在向脉络图添加一条与已有脉络不同的脉络(注意:连接 2个穴位但方向不同的脉络是不同的脉络,例如从穴位3到4的脉络与从4到3的脉络是不同的脉络,因此,图 1 中不能添加从 3 到 4 的脉络,但可添加从 4 到 3 的脉络),这条新脉络可以是从一个穴位连向自身的(例如,图 1 中可添加从 4 到 4 的脉络)。原脉络图添加这条新脉络后得到的新脉络图可能会出现脉络构成的环。
请你求出添加了这一条脉络之后的新脉络图的以穴位 1 为根的脉络树方案数。由于方案可能有太多太多,请输出方案数对 1,000,000,007 取模得到的结果。 

Input

输入文件的第一行包含四个整数 n、m、x和y,依次代表枫叶上的穴位数、脉络数,以及要添加的脉络是从穴位 x连向穴位y的。

接下来 m行,每行两个整数,由空格隔开,代表一条脉络。第 i 行的两个整数为ui和vi,代表第 i 条脉络是从穴位 ui连向穴位vi的。 

Output

输出一行,为添加了从穴位 x连向穴位 y的脉络后,枫叶上以穴位 1 为根的脉络树的方案数对 1,000,000,007取模得到的结果。

Sample Input

4 4 4 3
1 2
1 3
2 4
3 2

Sample Output

3

HINT

对于所有测试数据,1 <= n <= 100000,n - 1 <= m <= min(200000, n(n – 1) / 2),

1 <= x, y, ui, vi <= n。

Solution

QwQ挺(想)有(不)意(出)思(来)的一道题。
假设一开始不加x->y那条边,每一个非1的点选择一条入边就可以形成一棵树。正确性好像是从朱刘算法的推论得来的……
那么一开始的答案显然就是$\prod_{i=2}^nInd_i$,$Ind_i$表示$i$点的入度。
接着考虑加上x->y那条边,还按上面那样计算答案,显然会多出来成环这种不合法的方案。我们只要简单的容斥思想,计算出成环的方案然后用总方案减掉就是答案了。
什么时候才会成环呢?因为加入x->y这条边才成环的,所以x->y边一定是被选中的。所以任意一条y到x的路径都可以和边x->y成环。
这玩意儿可以拓扑排序的时候DP来做,设$f[i]$表示y到i路径的答案。
在从i转移到j的时候,j由随机选入边变成了强制选成环的边,所以要乘一个j的入度的逆元。

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<queue>
  4. #define N (100009)
  5. #define MOD (1000000007)
  6. using namespace std;
  7.  
  8. struct Edge{int to,next;}edge[N<<];
  9. int n,m,u,v,S,T,Ind[N],head[N],num_edge;
  10. long long inv[N],f[N],pinv[N],ans=;
  11. queue<int>q;
  12.  
  13. void add(int u,int v)
  14. {
  15. edge[++num_edge].to=v;
  16. edge[num_edge].next=head[u];
  17. head[u]=num_edge; Ind[v]++;
  18. }
  19.  
  20. void Toposort()
  21. {
  22. for (int i=; i<=n; ++i)
  23. if (!Ind[i]) q.push(i);
  24. f[T]=ans*pinv[T]%MOD;
  25. while (!q.empty())
  26. {
  27. int x=q.front(); q.pop();
  28. for (int i=head[x]; i; i=edge[i].next)
  29. {
  30. Ind[edge[i].to]--;
  31. if (!Ind[edge[i].to]) q.push(edge[i].to);
  32. f[edge[i].to]+=f[x]*pinv[edge[i].to]%MOD;
  33. f[edge[i].to]%=MOD;
  34. }
  35. }
  36. printf("%lld\n",((ans-f[S])%MOD+MOD)%MOD);
  37. }
  38.  
  39. int main()
  40. {
  41. scanf("%d%d%d%d",&n,&m,&S,&T);
  42. inv[]=; ++Ind[T];//注意Ind的变化
  43. for (int i=; i<=n; ++i)
  44. inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD;
  45. for (int i=; i<=m; ++i)
  46. scanf("%d%d",&u,&v),add(u,v);
  47. for (int i=; i<=n; ++i)
  48. ans=ans*Ind[i]%MOD;
  49. if (T==){printf("%lld\n",ans); return ;}
  50. for (int i=; i<=n; ++i) pinv[i]=inv[Ind[i]];
  51. --Ind[T]; Toposort();
  52. }

BZOJ4011:[HNOI2015]落忆枫音(DP,拓扑排序)的更多相关文章

  1. [BZOJ4011][HNOI2015]落忆枫音:拓扑排序+容斥原理

    分析 又是一个有故事的题目背景.作为玩过原作的人,看题目背景都快看哭了ToT.强烈安利本境系列,话说SP-time的新作要咕到什么时候啊. 好像扯远了嘛不管了. 一句话题意就是求一个DAG再加上一条有 ...

  2. bzoj4011[HNOI2015]落忆枫音 dp+容斥(?)

    4011: [HNOI2015]落忆枫音 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1125  Solved: 603[Submit][Statu ...

  3. 【bzoj4011】[HNOI2015]落忆枫音 容斥原理+拓扑排序+dp

    题目描述 给你一张 $n$ 个点 $m$ 条边的DAG,$1$ 号节点没有入边.再向这个DAG中加入边 $x\to y$ ,求形成的新图中以 $1$ 为根的外向树形图数目模 $10^9+7$ . 输入 ...

  4. BZOJ 4011: [HNOI2015]落忆枫音 计数 + 拓扑排序

    Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出 这样一个问题.  「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们 ...

  5. [luogu3244 HNOI2015] 落忆枫音(容斥原理+拓扑排序)

    传送门 Description 给你一张 n 个点 m 条边的DAG,1 号节点没有入边.再向这个DAG中加入边 x→y ,求形成的新图中以 1 为根的外向树形图数 模 10^9+7 . Input ...

  6. [BZOJ4011][HNOI2015]落忆枫音-[dp乱搞+拓扑排序]

    Description 传送门 Solution 假如我们的图为DAG图,总方案数ans为每个点的入度In相乘(不算1号点).(等同于在每个点的入边选一条边,最后一定构成一棵树). 然而如果加了边x- ...

  7. BZOJ4011: [HNOI2015]落忆枫音(dp 乘法原理)

    题意 题目链接 Sol 非常妙的一道题 设\(inder[i]\)表示\(i\)号节点的度数 首先如果是个DAG的话,可以考虑在每个点的入边中选一条边作为树形图上的边,这样\(ans = \prod_ ...

  8. 【题解】 [HNOI2015]落忆枫音 (拓扑排序+dp+容斥原理)

    原题戳我 Solution: (部分复制Navi_Aswon博客) 解释博客中的两个小地方: \[\sum_{\left(S是G中y→x的一条路径的点集\right))}\prod_{2≤j≤n,(j ...

  9. BZOJ 4011: [HNOI2015]落忆枫音( dp )

    DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). ---------------------------------------- ...

随机推荐

  1. JAVA实现多线程处理批量发送短信、APP推送

    /** * 推送消息 APP.短信 * @param message * @throws Exception */ public void sendMsg(Message message) throw ...

  2. Firebird 条件函数

    1.iif  IIF (<condition>, ResultT, ResultF) 示例: select iif( sex = 'M', 'Sir', 'Madam' ) from Cu ...

  3. Java如何实现form表单提交的数据自动对应实体类(源码)

    原文出自:https://blog.csdn.net/seesun2012 原生Java+JQuery form表单serializeArray提交自动对应java实体,这是一个实际的例子: html ...

  4. dbcp数据库连接池的java实现

    1.准备 导入jar包 commons-dbcp-1.4.jar commons-pool-1.3.jar 数据库驱动包,如:mysql-connector-java-5.1.28-bin.jar 2 ...

  5. C#实现Javascript的Splice方法

    最近开始学习Javascript语言,看到splice方法,以下引用其说明:该方法是一个通用删除和插入元素的方法,它可以在数组指定的位置开始删除或插入元素.其包括3个参数:第一个参数指定插入的起始位置 ...

  6. 纯手写实现HashMap

    1.hashmap的实现 ① 初始化 1)定义一个Node<K, V>的数组来存放元素,但不立即初始化,在使用的时候再加载 2)定义数组初始大小为16 3)定义负载因子,默认为0.75, ...

  7. 基于bootstrap的内容折叠功能

    加入js及css支持: <link rel="stylesheet" href="css/bootstrap.min.css"/> <scri ...

  8. struts2 执行流程及工作原理

    在Struts2框架中的处理大概分为以下的步骤  1 用户发送请求: 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过 ...

  9. JavaEE之servlet相关技术

    相关技术:为了灵活实现的不同路径(/hello)执行不同的资源( HeIIoMyServlet)我们需要使用XML进行配置;为了限定XML内容,我们需要使用xml约束(DTD或schema);为了获得 ...

  10. Android Studio修改app图标

    1.将下载好的图片放到app\src\main\res\drawable目录下 2.在AndroidManifest.xml下加入一句 android:icon="@drawable/??? ...