bzoj4011: [HNOI2015]落忆枫音
来源:互联网 发布:苹果5怎么改成4g网络 编辑:程序博客网 时间:2024/06/06 14:28
题目链接
bzoj4011
题目描述
【问题描述】
不妨假设枫叶上有 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。
题解
若不加x至y的边,图为一个有向无环图。树形图的个数即为
这样就可以DP了。记
不合法的方案就是
初值是:
拓扑排序一下就可以转移了。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#include<queue>#include<vector>using namespace std;#define N 100010#define P 1000000007queue<int>q;int x,y,u,v,n,m,tot,ans,first[N],p[N*2],du[N],tmp[N],f[N];struct edge{ int x,next;}e[N*2];char BUF[1000001],*buf,*end;#define getch() (buf==end?fread(BUF,1,1000000,stdin),buf=BUF,end=buf+1000000,*(buf++):*(buf++))inline void read(int &x){ static char c; for(c=getch();c<'0'||c>'9';c=getch()); for(x=0;'0'<=c&&c<='9';c=getch())x=x*10+c-'0';}inline void add(int x,int y){ e[++tot].x=y; e[tot].next=first[x]; first[x]=tot;}int main(){ read(n),read(m),read(x),read(y); for(int i=1;i<=m;i++){ read(u),read(v); add(u,v); du[v]++; tmp[v]++; } ans=1; du[y]++; for(int i=2;i<=n;i++) ans=(long long)ans*du[i]%P; if(y==1){printf("%d",ans); return 0;} p[1]=1; for(int i=2;i<=m+1;i++) p[i]=(long long)(P-P/i)*p[P%i]%P; f[y]=ans; for(int i=1;i<=n;i++) if(!tmp[i]) q.push(i); while(!q.empty()){ u=q.front(); q.pop(); f[u]=(long long)f[u]*p[du[u]]%P; for(int i=first[u];i;i=e[i].next){ f[e[i].x]+=f[u]; if(f[e[i].x]>=P)f[e[i].x]-=P; tmp[e[i].x]--; if(!tmp[e[i].x]) q.push(e[i].x); } } printf("%d",(ans-f[x]+P)%P); return 0;}
- bzoj4011: [HNOI2015]落忆枫音
- bzoj4011: [HNOI2015]落忆枫音
- BZOJ4011: [HNOI2015]落忆枫音
- bzoj4011[HNOI2015]落忆枫音
- 【BZOJ4011】【HNOI2015】落忆枫音
- 【bzoj4011】【hnoi2015】落忆枫音【精妙的动态规划】
- 【BZOJ4011】【HNOI2015】落忆枫音 拓扑图DP,
- 【bzoj4011】【HNOI2015】【落忆枫音】【dp+容斥原理】
- [朱刘算法推论 拓扑序DP] BZOJ4011 [HNOI2015]落忆枫音
- bzoj4011落忆枫音
- [BZOJ4011]HNOI2015落叶枫音|拓扑序DP
- BZOJ 4011: [HNOI2015]落忆枫音
- 【BZOJ 4011】 [HNOI2015]落忆枫音
- BZOJ 4011 HNOI2015 落忆枫音
- BZOJ 4011: [HNOI2015]落忆枫音
- BZOJ 4011 [HNOI2015]落忆枫音
- 4011: [HNOI2015]落忆枫音
- BZOJ 4011 [HNOI2015] 落忆枫音
- 1040. 有几个PAT(25)
- java 内部类总结
- 边看书边做边发挥-图书软件-9
- hdoj 5636 Shortest Path
- Eclipse创建Maven项目提示缺少maven-resources-plugin:2.6
- bzoj4011: [HNOI2015]落忆枫音
- JS调用OC方法(JavaScriptCore)
- 深度学习资料汇总
- linux 查看端口号占用情况
- 数据结构与算法系列----直插,快排,堆排,归并排序讲解
- Android UI优化
- [LeetCode]62. Unique Paths
- uml 关联相关设计模式描述
- 第二周上机实践项目——项目1-宣告“主权”