• [HAOI2016]食物链


    原题链接:https://www.luogu.org/problemnew/show/3183

    拓扑排序题

    题意简述:给出一个有向图,求由图中所有入度为零的点出发,有多少种路径到达出度为零的点(单点不计入)。

    拓扑排序,现将所有入度为零的点加到队列中,同时用一个数组f表示能达到这个点的路径条数,很显然,路径的零的点x,f[x]=1

    由各个点出发,将每个点的方案数加到它所能到达的点上,完成拓扑排序后,将所有出度为零的点的f值相加,用一个vis来记录是否有边连向这个点,判断是否需要忽略掉即可。

    #include<cstdio>
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    int n,m,cnt,l=1,r;
    int d[100005],c[100005],head[100005];
    int q[100005],f[100005],vis[100005];
    long long sum;
    struct edge
    {
        int u,v;
    }e[200005];
    void add(int u,int v)
    {
        e[++cnt].u=head[u];
        e[cnt].v=v;
        head[u]=cnt;
    }
    void top(int x)
    {
        for(int i=head[x];i;i=e[i].u)
        {
            int nxt=e[i].v;
            d[nxt]--;
            if(d[nxt]==0) q[++r]=nxt;
            f[nxt]+=f[x];
        }
    }
    int main()
    {
        read(n);read(m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            read(x);read(y);
            c[x]++;d[y]++;
            vis[x]++;vis[y]++;
            add(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(d[i]==0)
            {
                q[++r]=i;
                f[i]=1;
            }
        }
        while(l<=r)
        {
            top(q[l]);
            l++;
        }
        for(int i=1;i<=n;i++)
        {
            if(c[i]==0&&vis[i]!=0) sum+=f[i];
        }
        printf("%lld",sum);
        return 0;
    }
  • 相关阅读:
    小记---------sparkRDD的Transformation 和 Action 及案例 原理解释
    小记---------maxwell启动闪退问题
    小记---------spark组件与其他组件的比较 spark/mapreduce ;spark sql/hive ; spark streaming/storm
    kettle 创建作业发送邮件
    oracle查询表的结构
    ETL简介
    Oracle中分析函数
    谷歌浏览器快捷键
    Kettle入门
    Oracle基本知识
  • 原文地址:https://www.cnblogs.com/zeroform/p/8323437.html
Copyright © 2020-2023  润新知