传送门:http://blog.csdn.net/popoqqq/article/details/45194103
很文艺的题目
朱刘算法的推论 如果除根节点外每个点都选择一条入边,由于没有环,因此一定会形成一个树形图
去掉多余情况的过程是个拓扑序DP
#include<cstdio> #include<cstdlib> #include<algorithm> #define V G[p].v #define Mod 1000000007 using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } ll inv[200005]; inline void Pre(){ inv[1]=1; for (int i=2;i<=200001;i++) (inv[i]=(Mod-Mod/i)*inv[Mod%i])%=Mod; } struct edge{ int u,v; int next; }; edge G[200005]; int head[100005],inum; inline void add(int u,int v,int p){ G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p; } int lst[100005],icnt; int vst[100005]; inline void dfs(int u) { vst[u]=1; for (int p=head[u];p;p=G[p].next) if (!vst[V]) dfs(V); lst[++icnt]=u; } int n,m,x,y; int deg[100005]; ll f[100005]; int main() { int _u,_v; Pre(); freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); read(x); read(y); for (int i=1;i<=m;i++) read(_u),read(_v),add(_u,_v,++inum),deg[_v]++; deg[y]++; ll ans=1; for (int i=2;i<=n;i++) (ans*=deg[i])%=Mod; if (y==1) return printf("%lld\n",ans),0; dfs(1); reverse(lst+1,lst+n+1); f[y]=ans; for (int i=1;i<=n;i++) { int u=lst[i]; (f[u]*=inv[deg[u]])%=Mod; for (int p=head[u];p;p=G[p].next) (f[V]+=f[u])%=Mod; } (((ans-=f[x])%=Mod)+=Mod)%=Mod; printf("%lld\n",ans); }