zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    linux mysql添加用户名并实现远程访问
    bootstrap-datetimepicker时间控件的使用
    jquery图片左右来回循环飘动
    jquery 全选获取值
    设置linux编码utf-8
    nginx 自签名https
    Laravel 邮件配置
    memcachq队列安装
    开发与运维使用常用工具
    composer配置和安装php框架
  • 原文地址:https://www.cnblogs.com/zeroform/p/8323437.html
Copyright © 2011-2022 走看看