• 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;
    }

    这个时空比较爆炸。

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

  • 相关阅读:
    CGI(通用网关接口)
    PHP简介
    SEO搜索引擎优化/URL
    使用表单标签,与用户交互
    认识<img>标签,为网页插入图片
    使用mailto在网页中链接Email地址
    使用<a>标签,链接到另一个页面
    1037. Magic Coupon (25)
    1038. Recover the Smallest Number (30)
    1034. Head of a Gang (30) -string离散化 -map应用 -并查集
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/10960432.html
Copyright © 2020-2023  润新知