zoukankan      html  css  js  c++  java
  • luogu_4017【题解】最大食物链计数(拓扑排序)

    题目:https://www.luogu.org/problemnew/show/P4017

    由于这个题有严格的偏序关系(应该严格吧)。明显就可以想到拓扑排序。

    用吃与被吃建图。同时记录出度与入度。

    求拓扑排序的同时。如果谁的出度为 0 。则证明这条链到头。ans++。

    最后输出答案。

    代码如下:

    这是邻接表存图的,速度比较快。

    #include<bits/stdc++.h>
    #define sc(x) scanf("%d",&x)
    using namespace std;
    const int mod=80112002;
    struct edge{
        int from,to,nxt;
    }t[5000005];
    int n,m,du[5005],chu[5005],f[5005],ans,head[5005];
    queue<int> q;
    inline void topo()
    {
        for(int i=1;i<=n;i++)
            if(du[i]==0) q.push(i),f[i]=1;
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=head[now];i;i=t[i].nxt){
                int tt=t[i].to;
                f[tt]+=f[now];
                f[tt]%=mod;
                du[tt]--;
                if(du[tt]==0){
                    if(chu[tt]==0){
                        ans+=f[tt];
                        ans%=mod;
                    }
                    q.push(tt);
                }
            }
        }
    }
    int main()
    {
        sc(n),sc(m);
        int tot=0;
        while(m--){
            int a,b;
            sc(a),sc(b);
            t[++tot].from=a;t[tot].to=b;t[tot].nxt=head[a];
            head[a]=tot;
            du[b]++;chu[a]++;
        }
        topo();
        cout<<ans<<endl;
        // system("pause");
        return 0;
    }

    然而最一开始我写的是vector的,感觉写的比较短,不用管那么多。

    代码如下:

    #include<bits/stdc++.h>
    #define sc(x) scanf("%d",&x)
    using namespace std;
    const int mod=80112002;
    struct edge{
        int from,to;
        edge() {}
        edge(int _from,int _to): from(_from),to(_to) {}
    };
    vector<edge> g[5000005];
    int n,m,du[5005],chu[5005],f[5005],ans;
    queue<int> q;
    inline void topo()
    {
        for(int i=1;i<=n;i++)
            if(du[i]==0) q.push(i),f[i]=1;
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(vector<edge>::iterator it=g[now].begin();it!=g[now].end();it++){
                int t=it->to;
                f[t]+=f[now];
                f[t]%=mod;
                du[t]--;
                if(du[t]==0){
                    if(chu[t]==0){
                        ans+=f[t];
                        ans%=mod;
                    }
                    q.push(t);
                }
            }
        }
    }
    int main()
    {
        sc(n),sc(m);
        while(m--){
            int a,b;
            sc(a),sc(b);
            g[a].push_back(edge(a,b));
            du[b]++;chu[a]++;
        }
        topo();
        cout<<ans<<endl;
        // system("pause");
        return 0;
    }

    这个时空比较爆炸。

    但是感觉还是挺好写的(滑稽)。

  • 相关阅读:
    MySQL-5.6.xx-winx64 免安装版配置方法
    winForm窗体最大化的设置
    foreach内部做的一点事
    sqlserver创建同义词
    sql server 数据库创建链接服务器
    文件比对工具——WinMerge
    Devos病毒解决办法(转)
    设计模式学习笔记-单例模式
    Aspose.Word for DotNet 定位到每页,画笔 移动到某页。
    Word 固定文字或签名在底部
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/10960432.html
Copyright © 2011-2022 走看看