解法:動態規劃
對於不加邊時,原圖爲DAG,答案顯然是 ~ 點的入度相乘。
若所連的邊爲自環或連向點 。這時對答案沒有影響。
剩下的情況,設所連的邊爲 ,考慮計算包含邊 的生成樹方案數。
設 爲從 到 的一條單向路徑,該路徑不包含 。那麼
其中 可以dp求解。
時間複雜度 。
代碼
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
class FastFileReader{char buffer[10000001];char *h;int len;inline char gchar(){return *h++;}inline bool validdigit(char c){return c>='0' && c<='9';}public:inline void init(){len=fread(buffer,1,10000000,stdin);h=buffer;}inline int nextint(){register int i=0;register char c;do c=gchar();while(!validdigit(c));do{i=i*10+c-48;c=gchar();}while(validdigit(c));return i;}inline int nextsigned(){register int i=0,f=1;register char c;do{c=gchar();if(c=='-')f=-1;}while(!validdigit(c));do{i=i*10+c-48;c=gchar();}while(validdigit(c));return i*f;}inline long long nextlonglong(){register long long i=0;register char c;do c=gchar();while(!validdigit(c));do{i=i*10+c-48;c=gchar();}while(validdigit(c));return i;}inline long long nextsignedlonglong(){register long long i=0,f=1;register char c;do{c=gchar();if(c=='-')f=-1;}while(!validdigit(c));do{i=i*10+c-48;c=gchar();}while(validdigit(c));return i*f;}inline char nextchar(){register char c;do c=gchar();while(c<=' ');return c;}};
FastFileReader fs;
const long long p=1000000007ll;
int n,m,s,t,x,y,ind[100001];
long long f[100001],inv[100001],ans=1ll;
bool vis[100001];
vector<int> point[100001];
void dfs(int u){
vis[u]=true;
if(u==s||u==t){f[u]=u==s;return;}
for(int v:point[u]){if(!vis[v])dfs(v);(f[u]+=inv[ind[v]]*f[v]%p)%=p;}
}
int main(){
fs.init(),n=fs.nextint(),m=fs.nextint(),s=fs.nextint(),t=fs.nextint();
for(int i=1;i<=m;++i)x=fs.nextint(),y=fs.nextint(),point[x].push_back(y),++ind[y];
for(int i=(inv[0]=1)+(inv[1]=1);i<=n;++i)inv[i]=(p-p/i)*inv[p%i]%p;
for(int i=2;i<=n;++i)(ans*=ind[i])%=p;
if(s==t||t==1){printf("%lld",ans);return 0;}
dfs(1);
printf("%lld",(ans+=ans*inv[ind[t]]%p*f[1]%p)%=p);
}