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

    几个重点:

    1.从每个点任选一条入边,都可以成为一个树形图。

    2.于是考虑所有答案减去有环的答案。

    3.将要求的东西形式化表示出来,然后发现可以直接dp。。

    好厉害啊。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxv 100050
    #define maxe 200050
    #define mod 1000000007
    using namespace std;
    long long n,m,x,y,a,b,d[maxv],dp[maxv],inv[maxv],ans=1,nume=1,g[maxv],dv[maxv];
    queue <long long> q;
    struct edge
    {
        long long v,nxt;
    }e[maxe];
    void addedge(long long u,long long v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void get_table()
    {
        inv[1]=1;
        for (long long i=2;i<=n;i++) inv[i]=(-(mod/i)*inv[mod%i]%mod+mod)%mod;
    }
    void topusort()
    {
        for (long long i=1;i<=n;i++)
        {
            dv[i]=d[i];
            if (!d[i]) q.push(i);
        }
        while (!q.empty())
        {
            long long head=q.front();q.pop();
            for (long long i=g[head];i;i=e[i].nxt)
            {
                long long v=e[i].v;
                dp[v]+=dp[head]*inv[dv[v]]%mod;if (dp[v]>mod) dp[v]%=mod;
                if (!--d[v]) q.push(v);
            }
        }
    }
    int main()
    {
        scanf("%lld%lld%lld%lld",&n,&m,&x,&y);d[y]++;
        for (long long i=1;i<=m;i++)
        {
            scanf("%lld%lld",&a,&b);
            d[b]++;addedge(a,b);
        }
        for (long long i=2;i<=n;i++) ans=(ans*d[i])%mod;
        if (y==1) {printf("%d
    ",ans);return 0;}
        get_table();
        dp[y]=ans*inv[d[y]]%mod;d[y]--;
        topusort();
        printf("%lld
    ",(ans-dp[x]+mod)%mod);
        return 0;
    }
  • 相关阅读:
    手机抓包方法
    IBM appscan 9.0破解版分享
    C#打开新页面
    双城记
    卸载趋势
    测试环境搭建
    C#常用函数→ASP.NET篇
    C#常用函数--通用篇
    读>>>>白帽子讲Web安全<<<<摘要→我推荐的一本书→1
    TCP/IP网络编程技术基础
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6067684.html
Copyright © 2011-2022 走看看