zoukankan      html  css  js  c++  java
  • 落忆枫音

    首先对于一张拓扑图,生成树的个数ans-->除根节点以外的节点的入度之积

    但是加了一条边以后就变得不拓扑了,所以要减去所产生的不合法的情况,即统计由Y到X的路径条数

    对于包含这样的路径的不合法的"树",会有-->所有不包含于这条路径的点的入度的乘积种

    即-->ans/du[所有属于路径的节点]

    我们用f[i]表示节点i到Y的方案数,边界条件f[Y]=ans,除法用逆元搞定

     1     #include<bits/stdc++.h>
     2     using namespace std;
     3       
     4     typedef long long i64;
     5     #define mod 1000000007
     6     #define maxn 100005
     7     #define maxm 200005
     8     int cnt,v[maxm<<1],next[maxm<<1],first[maxn];
     9     int n,m,X,Y,q[maxn],in[maxn],du[maxn];
    10     i64 f[maxn];
    11     int read(){
    12         int tmp=0;
    13         char ch=0;
    14         while(!isdigit(ch))ch=getchar();
    15         while(isdigit(ch)){
    16             tmp=tmp*10+ch-'0';
    17             ch=getchar();
    18         }
    19         return tmp;
    20     }
    21     void add(int st,int end){
    22         v[++cnt]=end;
    23         next[cnt]=first[st];
    24         first[st]=cnt;
    25     }
    26     i64 qp(i64 bs,int x){
    27         i64 sum=1LL;
    28         while(x){
    29             if(x&1)sum=sum*bs%mod;
    30             bs=bs*bs%mod;
    31             x>>=1;
    32         }
    33         return sum;
    34     }
    35     void topo(){
    36         int head=0,tail=0;
    37         for(int i=1;i<=n;i++)
    38             if(!in[i])q[++tail]=i;
    39         while(head<tail){
    40             int x=q[++head];
    41             f[x]=f[x]*qp(du[x],mod-2)%mod;
    42             for(int e=first[x];e;e=next[e]){
    43                 f[v[e]]=(f[v[e]]+f[x])%mod;
    44                 if(!--in[v[e]])q[++tail]=v[e];
    45             }
    46         }
    47     }
    48     int main(){
    49         n=read(),m=read(),X=read(),Y=read();
    50         for(int i=1;i<=m;i++){
    51             int a,b;
    52             a=read(),b=read();
    53             add(a,b);
    54             in[b]++,du[b]++;
    55         }
    56         du[Y]++;
    57         i64 ans=1LL;
    58         for(int i=2;i<=n;i++)
    59             ans=ans*du[i]%mod;
    60         if(Y==1||X==Y){
    61             printf("%lld
    ",ans);
    62             return 0;
    63         }
    64         f[Y]=ans;
    65         topo();
    66         ans=(ans-f[X]+mod)%mod;
    67         printf("%lld
    ",ans);
    68         return 0;
    69     }
    70 
    View Code
  • 相关阅读:
    php 接收表单 方法的区别
    php上传图片---初级版
    php 验证格式的函数总结
    行为类模式分析
    深入理解java虚拟机
    JVM生产环境参数实例及分析
    redis 排序(转)
    八种常用的排序算法(转)
    CAS原理分析
    Redis使用总结之与Memcached异同(转)
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5093747.html
Copyright © 2011-2022 走看看