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;
    }
  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/xcg123/p/11295782.html
Copyright © 2011-2022 走看看