BZOJ 4011: [HNOI2015]落忆枫音 计数 + 拓扑排序
Description
「恒逸,你相信灵魂的存在吗?」
Input
输入文件的第一行包含四个整数 n、m、x和y,依次代表枫叶上的穴位数、脉
Output
输出一行,为添加了从穴位 x连向穴位 y的脉络后,枫叶上以穴位 1 为根的脉
如果没有那条返祖边,那么答案就是 $\prod_{i=2}^{n}deg(i)$,即除了 $1$ 号点之外所有点的入度之积.
如果加入一条返祖边,可能会形成环,那就要减去那些不合法的部分.
那么假设我们已经确定了一个环 $S$.
那么如果去掉环 $S$,那么方案数就是 $tot-\frac{tot}{\prod_{i\in S}^{}deg(i)}$
即把 $S$ 的贡献除掉,剩下的边随便连.
如果依次枚举每个环的话会很麻烦,不妨令 $f_{i}$ 表示所有从 $t$ 走到 $i$ 的路径的上述答案.
那么最终答案就会是 $tot-f_{s}$.
考虑转移:
考虑 $u\Rightarrow v$,则 $f_{v}=\frac{\sum f_{u}}{deg_{v}}$.
这么转移就行了,就是一个拓扑序 $dp$.
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstring>
#define N 100005
#define mod 1000000007
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
namespace IO
{
char *p1,*p2,buf[100000];
#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
int rd() {int x = 0, f = 1;char c = nc();while (c < 48) {if (c == '-')f = -1;c = nc();}while (c > 47) {x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();}return x * f;}
};
queue<int>q;
ll qpow(ll base,ll k) { ll tmp=1; for(;k;base=base*base%mod,k>>=1)if(k&1) tmp=tmp*base%mod; return tmp; }
ll inv(int x) { return qpow(x, mod-2); }
ll ans=1;
int n,m,s,t,edges;
int hd[N],nex[N<<1],deg[N],dp[N],tp[N],to[N<<1];
inline void addedge(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; }
inline ll bfs()
{
int i;
dp[t]=ans;
for(i=1;i<=n;++i) if(!tp[i]) q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
dp[u]=dp[u]*inv(deg[u])%mod;
for(i=hd[u];i;i=nex[i])
{
int v=to[i];
dp[v]=(dp[v]+dp[u])%mod;
--tp[v];
if(!tp[v]) q.push(v);
}
}
return (ans-dp[s]+mod)%mod;
}
int main()
{
using namespace IO;
int i,j;
// setIO("input");
n=rd(),m=rd(),s=rd(),t=rd(),++deg[t];
for(i=1;i<=m;++i)
{
int x=rd(),y=rd();
++deg[y], ++tp[y], addedge(x,y);
}
for(i=2;i<=n;++i) ans=ans*deg[i]%mod;
printf("%lld\n",t==1?ans:bfs());
return 0;
}
BZOJ 4011: [HNOI2015]落忆枫音 计数 + 拓扑排序的更多相关文章
- BZOJ 4011: [HNOI2015]落忆枫音( dp )
DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). ---------------------------------------- ...
- BZOJ4011:[HNOI2015]落忆枫音(DP,拓扑排序)
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂……我们也 ...
- BZOJ 4011 HNOI2015 落忆枫音 DAG上的dp(实际上重点在于分析)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题意概述:给出一张N点的DAG(从1可以到达所有的点),点1的入度为0.现在加一条原 ...
- BZOJ 4011 HNOI2015 落忆枫音
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题目很长,写得也很有诗意与浪漫色彩,让我们不禁感叹出题人是一个多么英俊潇洒的人. 所 ...
- 【题解】 [HNOI2015]落忆枫音 (拓扑排序+dp+容斥原理)
原题戳我 Solution: (部分复制Navi_Aswon博客) 解释博客中的两个小地方: \[\sum_{\left(S是G中y→x的一条路径的点集\right))}\prod_{2≤j≤n,(j ...
- 【bzoj4011】[HNOI2015]落忆枫音 容斥原理+拓扑排序+dp
题目描述 给你一张 $n$ 个点 $m$ 条边的DAG,$1$ 号节点没有入边.再向这个DAG中加入边 $x\to y$ ,求形成的新图中以 $1$ 为根的外向树形图数目模 $10^9+7$ . 输入 ...
- [luogu3244 HNOI2015] 落忆枫音(容斥原理+拓扑排序)
传送门 Description 给你一张 n 个点 m 条边的DAG,1 号节点没有入边.再向这个DAG中加入边 x→y ,求形成的新图中以 1 为根的外向树形图数 模 10^9+7 . Input ...
- [BZOJ4011][HNOI2015]落忆枫音:拓扑排序+容斥原理
分析 又是一个有故事的题目背景.作为玩过原作的人,看题目背景都快看哭了ToT.强烈安利本境系列,话说SP-time的新作要咕到什么时候啊. 好像扯远了嘛不管了. 一句话题意就是求一个DAG再加上一条有 ...
- 4011: [HNOI2015]落忆枫音
4011: [HNOI2015]落忆枫音 链接 分析: 原来是一个DAG,考虑如何构造树形图,显然可以给每个点找一个父节点,所以树形图的个数就是$\prod\limits_u deg[u]$. 那么加 ...
随机推荐
- AGC037 C Numbers on a Circle【思维】
题目传送门 题意 这道题被某大佬改编拿来出成考试题,是长这个样子的: 好的,其实这才是真正的题意: 给定初始序列和最终序列,每次选择一个数变成自己和相邻2个数的和.问初始序列是否可以变为最终序列,若可 ...
- tableau备份
备份:数据库备份:https://help.tableau.com/current/server-linux/zh-cn/cli_maintenance_tsm.htm#tsm https://hel ...
- doT学习(一)之语法
简介 创建搜索最快和简洁的JavaScript模板函数,强调V8和nodejs下的性能,它在nodejs和浏览器上都显示了很好的性能. dot.js速度快,体积小,没有依赖关系,源js代码只有140行 ...
- --解决Lock wait timeout exceeded; try restarting transaction
--解决Lock wait timeout exceeded; try restarting transaction select * from information_schema.innodb_t ...
- webstorm 如何去掉下划线
当前webstorm版本:2018.3.5 百度了也没找到解决办法,最终结合了和群友的给的位置,找到了修改地方,只能怪版本迭代太快了,要适应 右上角Effects点掉就可以了
- Git 设置 用户名 和 邮箱
git config --global user.name "Vincent" git config --global user.email "********@qq.c ...
- 77. Combinations (JAVA)
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...
- Linux日常之命令tee
命令tee (1)读取标准输入的数据,并将其内容输出成文件 (2)主要用于重定向到文件 常用参数 -a,将读取的内容追加到文件的后面,而不是覆盖(在默认的情况下是覆盖) 命令tee与重定向的区别 重定 ...
- 对OO原则的个人理解
1.单一职责原则.(Single Responsibility Principle) 注解:社会化大生产分工要细.具体每个人最好只做一件事(不要一人兼多职),这样如果这个人请假或辞职,对生产不会产生影 ...
- SugarCRM开发入门
SugarCRM官网下载地址:https://sourceforge.net/projects/sugarcrm/ 概述 Sugar最初是基于LAMP(Linux.Apache.MySQL和PHP)运 ...