Code:
#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]落忆枫音 计数 + 拓扑排序
原文:https://www.cnblogs.com/guangheli/p/11390307.html