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

    Description

    给出一个有n个点和m条边的有向无环图,1号节点入度为0。这个有向无环图存在一个树形子图,是以1号节点为根的包含全部n个点的一棵树。该树形子图可能有多种可能性。

    现在向图中加入一条与已有边不同的有向边(连接两个节点但方向不同视为不同的边),这条边可连向自身。原有向无环图添加新边后得到的新图可能会出现环。

    求新图中以1为根的树形子图的方案数。(对1000000007取模)


    Solution

    我们可以得到,有向无环图中树形子图的方案数为2号节点到n号节点的入度的乘积。

    设新边为(u,v),新图中2号节点到n号节点的入度的乘积为sum。

    若v==1,则答案为sum。

    否则令f[i]表示原图中1号节点到i号节点所有路径的价值之和除以该点当前入度(即乘上当前入度模1000000007的逆元),ans=sum-f[u]。

    初始值:f[v]=sum。

    我们在原图中从1号节点开始进行拓扑排序。

    若加入新边后不构成环,由于原图为DAG,则不存在从v节点到u节点的路径,f[u]=0,满足答案为2号节点到n号节点的入度的乘积,即ans=sum;

    若加入新边后构成环,f[u]的值即新图中取了整个环的方案数,则ans=sum-f[u]。

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 using namespace std;
     6 typedef long long ll;
     7 const ll mod=1000000007;
     8 struct edge{
     9     int to,next;
    10 }e[200010];
    11 int n,m,x,y,head[100010];
    12 int a[100010]={0},in[100010]={0};
    13 ll ans=1,inv[100010]={0,1},f[100010]={0};
    14 ll solve(){
    15     queue<int>q;
    16     while(!q.empty())
    17         q.pop();
    18     q.push(1);
    19     f[y]=ans;
    20     while(!q.empty()){
    21         int u=q.front();
    22         q.pop();
    23         f[u]=f[u]*inv[a[u]]%mod;
    24         for(int i=head[u];~i;i=e[i].next){
    25             int v=e[i].to;
    26             f[v]=(f[v]+f[u])%mod;
    27             in[v]--;
    28             if(in[v]==0)
    29                 q.push(v);
    30         }
    31     }
    32     return (ans-f[x]+mod)%mod;
    33 }
    34 int main(){
    35     memset(head,-1,sizeof(head));
    36     scanf("%d%d%d%d",&n,&m,&x,&y);
    37     for(int i=2;i<=n+1;i++)
    38         inv[i]=(mod-mod/i*inv[mod%i]%mod)%mod;
    39     a[y]++;
    40     for(int i=1;i<=m;i++){
    41         int u,v;
    42         scanf("%d%d",&u,&v);
    43         e[i]=(edge){v,head[u]};
    44         head[u]=i;
    45         in[v]++;a[v]++;
    46     }
    47     for(int i=2;i<=n;i++)
    48         ans=ans*a[i]%mod;
    49     printf("%lld
    ",y==1?ans:solve());
    50     return 0;
    51 }
  • 相关阅读:
    MyISAM表锁的解决方案
    RSA数字证书管理
    Self Host WebApi服务传输层SSL加密(服务器端+客户端调用)
    WebApi服务Uri加密及验证的两种方式
    利用MVC的自定义过滤器FilterAttribute、IActionFilter、IExceptionFilter实现异常处理等功能
    html页面中meta的作用
    [转]REST简介
    [转]webApi 参数传递总结
    REST服务中的异常处理
    REST服务返回自定义的HttpResponseMessage
  • 原文地址:https://www.cnblogs.com/gzez181027/p/bzoj4011.html
Copyright © 2011-2022 走看看