zoukankan      html  css  js  c++  java
  • [BZOJ4011][HNOI2015]落忆枫音-[dp乱搞+拓扑排序]

    Description

    传送门

    Solution

    假如我们的图为DAG图,总方案数ans为每个点的入度In相乘(不算1号点)。(等同于在每个点的入边选一条边,最后一定构成一棵树)。

    然而如果加了边x->y后图中带了环,则ans个方案中不合法的方案一定是选择了原DAG图中y->x的路径后又选了额外加的边x->y。

    假如说我们找到了某条y->x的路径,则选了这条路径的不合法方案数就为除了该路径上的其他点入度相乘。

    考虑在原图上dp。假如原图上存在了一条u->v的路径,dp[u]+=dp[v]*inv(In[v])。边界dp[t]=ans*inv(In[t])。

    为了保证当我们处理到v的时候所有与指向u的边已经被处理完毕,dp得按照拓扑序进行。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    ll ksm(ll x,int k)
    {
        ll re=1;
        while (k)
        {
            if (k&1) re=re*x%mod;
            k>>=1;
            x=x*x%mod;
        }
        return re;
    }
    
    int n,m,s,t,x,y,In[100010];
    struct node{int y,nxt;
    }g[200010];int h[100010],tot=0;
    ll ans,inv[100010];
    ll dp[100010];
    queue<int>q;
    void bfs()
    {
        dp[t]=ans*inv[t];
        for (int i=1;i<=n;i++) if (!In[i]) q.push(i);
        while (!q.empty())
        {
            x=q.front();
            q.pop();
            for (int i=h[x];i;i=g[i].nxt)
            {
                In[g[i].y]--;
                if (!In[g[i].y]) q.push(g[i].y);
                dp[g[i].y]=(dp[g[i].y]+dp[x]*inv[g[i].y]%mod)%mod;
            }
        }
        ans-=dp[s];ans%=mod;if (ans<0) ans+=mod;
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            g[i]=node{y,h[x]};h[x]=i;
            In[y]++;
        }
        In[t]++;ans=1;
        for (int i=2;i<=n;i++) inv[i]=ksm(In[i],mod-2),ans=ans*In[i]%mod;
        if (t==1) {cout<<ans;return 0;}
        In[t]--;
        bfs();
        cout<<ans;
    }
  • 相关阅读:
    图的最大匹配算法
    二分图的最小顶点覆盖 最大独立集 最大团
    后缀数组:倍增法和DC3的简单理解
    后缀自动机浅析
    微积分学习笔记一:极限 导数 微分
    微积分学习笔记二
    微积分学习笔记三:定积分
    微积分学习笔记四:空间向量基础
    微积分学习笔记五:多元函数微积分
    程序员之路--回顾2015,展望2016
  • 原文地址:https://www.cnblogs.com/coco-night/p/9526097.html
Copyright © 2011-2022 走看看