一个 D A G DAG DAG的生成树个数很容易算,就是给每个点选一个父亲 ( 1 为 根 ) (1为根) (1为根)
∏ i = 2 n i n [ i ] \prod\limits_{i=2}^nin[i] i=2∏nin[i]
现在新增一条 s s s到 t t t的边,原来的选择方案可能就会成环
而且必定包括 s s s到 t t t这条边
假设图中一个环 a 1 a 2 . . . a k \ a_1\ a_2...a_k a1 a2...ak
包括这个环的方案数有多少呢??
其实就是固定这个环中所有点的父亲,其余点任意
∏ i = 2 n i n [ i ] ∏ i = 1 k i n [ a [ i ] ] \frac{\prod\limits_{i=2}^nin[i]}{\prod\limits_{i=1}^kin[a[i]]} i=1∏kin[a[i]]i=2∏nin[i]
减去这些不合法的方案就好了.
由于环一定包含 s s s到 t t t的边,那我们可以从 t t t向 s s s找路径
路径上的点一定可以构成环
定义 f [ v ] = ∏ i = 2 n i n [ i ] ∏ i = 1 v i n [ a [ i ] ] f[v]=\frac{\prod\limits_{i=2}^nin[i]}{\prod\limits_{i=1}^vin[a[i]]} f[v]=i=1∏vin[a[i]]i=2∏nin[i]
其中分母的点集是 t t t到 v v v路径上所有点的集合
那么若有 v v v到 u u u的路径,则有转移
f [ u ] = ∑ v f [ v ] i n [ u ] f[u]=\frac{\sum\limits_{v}f[v]}{in[u]} f[u]=in[u]v∑f[v]
那么答案就是 ∏ i = 2 n i n [ i ] − f [ s ] \prod\limits_{i=2}^nin[i]-f[s] i=2∏nin[i]−f[s]
特别注意当 t = 1 t=1 t=1需要特判
因为 1 1 1是不会把任何点看作父亲的,所以这种情况下不可能有环
直接输出
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5+7;
const int mod = 1e9+7;
int n,m,s,t,in[maxn],ans1=1,ans2=1,f[maxn],vis[maxn];
struct edge{
int to,nxt;
}d[maxn]; int head[maxn],cnt=1;
void add(int u,int v){ d[++cnt] = (edge){v,head[u]},head[u] = cnt; }
int quick(int x,int n)
{
int ans = 1;
for( ; n ; n>>=1,x=x*x%mod )
if( n&1 ) ans = ans*x%mod;
return ans;
}
int dfs(int u)
{
if( vis[u] ) return f[u];
vis[u] = 1;
for(int i=head[u];i;i=d[i].nxt )
{
int v = d[i].to;
f[u] += dfs(v); f[u] %= mod;
}
f[u] = f[u]*quick( in[u],mod-2 )%mod;
return f[u];
}
signed main()
{
cin >> n >> m >> s >> t;
in[t]++;
for(int i=1;i<=m;i++)
{
int l,r; cin >> l >> r;
add(r,l); in[r]++;
}
for(int i=2;i<=n;i++)
ans1 = ans1*in[i]%mod;
if( t==1 )
{
cout << ans1;
return 0;
}
vis[t] = 1;
f[t] = ans1*quick( in[t],mod-2 )%mod;
cout << (( ans1-dfs(s) )%mod+mod)%mod;
}