• P4017 最大食物链计数


    题目链接https://www.luogu.com.cn/problem/P4017

    知识点:拓扑排序+动态规划

    一、刚开始审题不清,误认为是求AOV最长生物链上生物的个数,便出现如下代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int p=80112002;
     4 int n, m, ans;
     5 vector<int>g[5005];
     6 int dp[5005], ind[5005];
     7 queue<int>que;
     8 int main()
     9 {
    10     scanf("%d%d", &n, &m);
    11     for(int i=1; i<=m; i++){
    12         int a, b;
    13         scanf("%d%d", &a, &b);
    14         g[b].push_back(a);
    15         ind[a]++;
    16     }
    17     for(int i=1; i<=n; i++)
    18         if(!ind[i]){
    19             dp[i]=1;
    20             que.push(i);
    21         }
    22     while(!que.empty()){
    23         int f=que.front();
    24         for(int i=0; i<g[f].size(); i++){
    25             int t=g[f][i];
    26             dp[t]=max(dp[t], dp[f]+1);
    27             ind[t]--;
    28             if(!ind[t])
    29                 que.push(t);
    30         }
    31         que.pop();
    32     }
    33     for(int i=1; i<=n; i++)ans=max(ans, dp[i]);
    34     printf("%d", ans%p);
    35     
    36     return 0;
    37 }

    结果爆0

    重新审题后发现一下关键信息:(这里的“最大食物链”,指的是生物学意义上的食物链,即最左端是不会捕食其他生物的生产者,最右端是不会被其他生物捕食的消费者。)重要信息

    经过样例多次尝试分析得知要求:DAG中路径数(起始点为入度为0的生物,终点为出度为0的路径数)

    根据题意分析:设dp[i]为起始点(入度为0的点)到达顶点i的路径数,初始值入度为0的点dp[]为1

              拓扑排序过程中状态转移方程为dp[i]=sum(dp[可吃i])

           答案为 sum(dp[出度为0])

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int p=80112002;
     4 int n, m, ans;
     5 vector<int>g[5005];
     6 int dp[5005], ind[5005], outd[5005];//dp[i]表示从起始点到i的路径数 in[i]统计入度 out[i]统计出度 
     7 queue<int>que;
     8 int main()
     9 {
    10     scanf("%d%d", &n, &m);
    11     for(int i=1; i<=m; i++){
    12         int a, b;
    13         scanf("%d%d", &a, &b);
    14         g[b].push_back(a);//统计b能吃的生物 
    15         ind[a]++;//统计a的入度 :即a作为被吃生物的对数 
    16     }
    17     for(int i=1; i<=n; i++){
    18         if(!ind[i]){//入度为0的生物dp初始化为1,加入队列 
    19             dp[i]=1;
    20             que.push(i);
    21         }
    22         if(!g[i].size())
    23             outd[i]=1;//统计出度为0的生物,答案要求所有出度为0生物dp之和 ,可在样例中添加节点分析 
    24     }
    25         
    26     while(!que.empty()){
    27         int f=que.front();
    28         for(int i=0; i<g[f].size(); i++){//查找跟f相连接的点,即能被f吃掉的生物 
    29             int t=g[f][i];
    30             dp[t]=(dp[t]%p+dp[f]%p)%p;//状态转移方程,画图分析可得 
    31             ind[t]--;//入度减一 
    32             if(!ind[t])//如果度为0则进入下一阶段 
    33                 que.push(t);
    34         }
    35         que.pop();
    36     }
    37     for(int i=1; i<=n; i++)
    38         if(outd[i])//统计出度为0,即生物链终点的dp之和 
    39             ans=(ans%p+dp[i]%p)%p;
    40     
    41     printf("%d", ans%p);
    42     
    43     return 0;
    44 }
  • 相关阅读:
    SpringCloud
    SpringCloud
    一个表的字段更新另一个表的字段
    MYSQL5.7 sql_mode=only_full_group_by
    CentOS7 防火墙操作
    log4j DailyRollingFileAppender, DatePattern 配置
    Fiddler抓包-会话框添加查看get与post请求类型选项
    Fiddler抓包-工具介绍(request和response)
    Fiddler抓包-get与post请求
    Fiddler抓包-只抓APP的请求
  • 原文地址:https://www.cnblogs.com/tflsnoi/p/14764912.html
Copyright © 2020-2023  润新知