zoukankan      html  css  js  c++  java
  • P3183 [HAOI2016]食物链

    原题链接  https://www.luogu.org/problem/P3183

    一道经典的拓扑排序的题目~

    直接说思路吧:

    1. 在输入的过程中,我们要统计每个点的出度和入度;

    2. 进行一遍拓扑排序,同时给每个点维护一个 sum 值,表示从起点(入度为0的点)走到这个点有多少种方案,对于每条边的终点,它的 sum 值都要加上这条边起点的 sum 值;

    3. 如果有一个点的出度为 0,那么就说明这条食物链已经走到了最高级消费者,我们将答案加上这个点的 sum;

    4. 最后输出答案就好了;

    说的有点快?来个样例解释一下下:

    我们先找到入度为 0 的点:

    进行拓扑排序:

    挺详细了吧(逃~

    下面上AC代码喽:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    int read()
    {
        char ch=getchar();
        int a=0,x=1;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') x=-x;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            a=(a<<1)+(a<<3)+(ch-'0');
            ch=getchar();
        }
        return a*x;
    }
    const int mod=80112002;
    int n,m,u,v,ans,edge_sum;
    int in[200001],out[200001],head[400001],sum[200001];
    struct node
    {
        int id,len,to,next;
    }a[500001];
    void add(int from,int to)
    {
        edge_sum++;
        a[edge_sum].next=head[from];
        a[edge_sum].to=to;
        head[from]=edge_sum;
    }
    void topo()
    {
        queue<int> q;
        for(int i=1;i<=n;i++)
        {
            if(!in[i]&&out[i])       //题目中说一个孤立的生物不能算一条食物链,也就是说起点还要有出度          
            {
                q.push(i);
                sum[i]=1;             //起点的方案数只能是1 
            }
        }
        int f;
        while(!q.empty())
        {
            f=q.front();
            q.pop();
            if(!out[f])              //如果发现这个点出度是0,统计到答案里 
            {
                ans+=sum[f];
                continue;
            }
            for(int i=head[f];i;i=a[i].next)
            {
                int zd=a[i].to;
                sum[zd]+=sum[f];     //终点的sum+=起点的sum 
                in[zd]--;
                if(!in[zd]) q.push(zd);            
            }
        }
        printf("%d
    ",ans);          //最后答案 
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            u=read();
            v=read();
            add(u,v);
            in[v]++;                 //统计入度 
            out[u]++;                //统计出度 
        }
        topo();                      //拓扑排序 
        return 0;
    }
  • 相关阅读:
    kafka 项目实战
    7.DHCP的相关命令
    3.centos 7执行service iptables save报错问题
    39.NFS(网络文件系统)
    37.Samba 文件共享服务1--配置共享资源
    36.Samba 文件共享服务1--安装及配置参数解释
    35.简单文件传输协议
    34.vsftpd服务程序--虚拟用户模式
    33.vsftpd服务程序--本地用户模式
    32.vsftpd服务程序--匿名开放模式
  • 原文地址:https://www.cnblogs.com/xcg123/p/11295782.html
Copyright © 2011-2022 走看看