题目:生产口罩

链接:http://class.51nod.com/Classes/Problem.html#courseProblemId=1718&classId=129
//注:题目来自51nod
这道题是一道集拓补排序和DP的好题,而且还有几个细节值得注意,先讲大体思路,再讲细节。
题目:
在这套方案里,有n个自动化工厂,分别对应着生产口罩的不同工序。不过,一些自动化工厂要开始进行自己的工序,必须要先等待另外一些工厂完成自己的工序,我们把这些工序称为前置工序。

每个工厂完成自己的工序都需要一定的时间,且只有所有工厂都完成自己的工序,口罩生产才能完成。

现在告诉你每个工厂完成工序需要的时间,以及每个工厂进行自己工序需要的前置工序,问最早什么时候口罩生产才能完成

思路:
实际上所谓的“前置工序”实际上就是有向边,一个工厂是一个节点,整个方案就是一个有向图
所以这不就是套拓补排序模板吗

在此题中我们的目的是求出最短时间,所以对于每一个点,我们都需要求出Ta的最短时间。但怎么求呢?
对于每一个点都有很多个入边,因此我们只需要求出Ta所有入边的最短时间,在选择一个最长的加上本点的时间即可。

代码实现:
我们都知道拓补排序的核心思路是每次删去一条边,然后判断此点是否被“解锁”,是则加入队列,但是如果我们删除了所有通向一个点A的边,那我们怎么才能求出最短时间呢?
我们可以设time[i]表示完成i点的任务需要时间,ans[i]表示从头到完成i点需要的总时间,fa表示通向i节点的节点,在删除之前,比较到底是ans[i](即以前求出的最长路经)大还是time[i]+ans[fa](从fa节点到i节点)大,选择更大的一个赋值给ans[i]即可。

细节方面:
第一个细节:从哪一个节点开始?
如图:

这种图像该从哪一个开始Bfs?
我目前看到的题解是说在Ta们(入度为零)前面再建立一个节点,并指向Ta们,如图

但是这样做可能会很麻烦,于是可以这么做,对于入度为零的节点,直接把Ta放在队列里,并以第一个入队的开始,这样就不会忽略一个节点了。

第二个细节:最终答案怎么算?
还是那张图:

如果按Bfs算的话最终结果一定是6,但是4也得算啊,那怎么办呢?
还是那个题解,Ta的想法是在这种情况下,在像4,6这样的节点后在加一个新节点,如图:

这就更麻烦了对不对?那怎么办呢?
实际上更简单,因为最短时间只会随着有向边逐渐增加,而不会减小,所以拓补排序结束以后我们就一个一个的遍历节点,找到最大的ans[]即可。

喜闻乐见的代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<string>
#define Max(a,b) (a) > (b) ? (a) : (b)
using namespace std;
int n,m;
int book[200010];
int enter[200001];
int head = 1,tail = 1;
int que[2000001];
long long ans[200001];
long long time[200001];
vector<int> G[200001];
void Bfs(int st){while(head != tail){int t = que[head];for(int i = 0,len = G[t].size() ;i < len;i++){enter[G[t][i]]--;ans[G[t][i]] = Max(ans[G[t][i]],ans[t] + time[G[t][i]]);if(enter[G[t][i]] == 0){que[tail++] = G[t][i];book[G[t][i]] += 1;}}head++;}
}
int main(){scanf("%d%d",&n,&m);int u,v;for(int i = 1;i <= n;i++){scanf("%lld",&time[i]);ans[i] = time[i];}for(int i = 1;i <= m;i++){scanf("%d%d",&u,&v);G[u].push_back(v);enter[v]++; }int t = -1;for(int i = 1;i <= n;i++){if(enter[i] == 0){t = i;que[tail++] = i;}}Bfs(t);long long res = -99999999;for(int i = 1;i <= n;i++){res = Max(res,ans[i]);}printf("%lld",res);return 0;
}

本文到这里结束了,感谢阅读。

51nod-生产口罩(拓补排序+DP)by zyz相关推荐

  1. 【BZOJ3036】绿豆蛙的归宿 拓补排序+概率

    [BZOJ3036]绿豆蛙的归宿 Description 随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度. ...

  2. 奖金(拓补排序的应用)

    谁应该高谁的入度++,并记录下谁比低的高(低的得出度),所以入度为零的就是最低的(好不公平),找出所有最低的,将他们算作一层,奖金++(算是拓补排序吧) #include<cstdio> ...

  3. HDU4324 - Triangle LOVE 拓补排序

    HDU4324 - Triangle LOVE : http://acm.showproblemhdu.edu.cn/.php?pid=4324 标准的拓补排序,上代码 : #include < ...

  4. leetcode *210. 课程表 II(拓补排序)(2020.5.17)

    [题目]*210. 课程表 II 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前需要一些先修课程. 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们 ...

  5. Aov网络与拓补排序的实现

    测试的节点分布如下: 测试代码如下: /** 拓补排序的实现,使用邻接链表存储有向图 */ #include <iostream> #include <cstdio> #inc ...

  6. 每日一题30:拓补排序

    问题描述 所谓拓补排序就是确定图中节点的一种顺序,使得某些在别的节点访问之前不能访问到的节点排在后面.所以该算法的核心是每一步选择一个没有入度的节点,因为没有入度意味着该节点没有前驱,得到一个节点后, ...

  7. 士兵排队问题(拓补排序)(附简要拓补排序思想及算法)

    题目描述 有N个士兵(1<=N<=100),编号依次为1,2,...,N.队列训练时,指挥官要把士兵从高到矮排成一行,但指挥官只知道"1 比2 高,7 比 5高"这样的 ...

  8. 后缀自动机求多个串的最长公共子串+拓补排序讲解+LCS2 - Longest Common Substring II

    网上所有关于后缀自动机拓补排序的文章,都默认读者会拓补排序,简直了. 后缀自动机的拓补排序,就是按照长度进行排序,在进行特定操作的时候,通过较长的后缀来更新较短的后缀.那么也就是通过拓补排序中排名靠后 ...

  9. POJ 1094拓补排序

    POJ 1094拓补排序问题,需要加一些判断 #include <cstdio> #include <queue> #include <vector> #inclu ...

最新文章

  1. 深入跨域问题(2) - 利用 CORS 解决跨域
  2. 各维度 特征 重要程度 随机森林_机器学习算法——随机森林
  3. ASP.NET生成静态页面方法大全(2)
  4. linux中最常用命令
  5. JAVA OOP(二)——方法的重载、构造方法以及this关键字
  6. svnserver配置文件详解
  7. 基于稀疏表示理论的图像去噪
  8. Solaris10上修改hostid
  9. 用php实现基本功能,php实现文件管理与基础功能操作的方法
  10. 用python的Turtle库画一个笑脸
  11. Python hash函数详解
  12. html文本框后面紧挨着按钮,Word题目与答案
  13. 2023年大学毕业生,我有话想对你说
  14. Excel -- 实用技巧
  15. 服务器的备份文件在哪里找,云服务器系统如何备份文件在哪里看
  16. 我将进化成一条狗(5)——VR和AR
  17. 基于matlab的pcm设计实验报告,基于MATLAB的PCM系统仿真课程设计
  18. UEM系列(一)用户体验管理介绍
  19. 抖音精选联盟小店最新规则;商家千万别触碰这些红线;丨国仁网络资讯
  20. 国家信息安全水平考试

热门文章

  1. 计算机组装兴趣小组考核,中职计算机专业课程学生成绩考核之我见
  2. 杭电考研计算机专业课_2019杭电计算机考研初试科目、参考书目、报录比汇总...
  3. 2022氟化工艺考试试题及答案
  4. 【300+精选大厂面试题持续分享】大数据运维尖刀面试题专栏(九)
  5. iframe语法小结
  6. 好消息,个人也可以申请支付宝支付了
  7. 计算机网络开发与管理专业就业前景,计算机网络与安全管理专业就业前景和就业方向分析...
  8. 计算机网络课论文参考文献,热门计算机网络课程论文参考文献 计算机网络课程专著类参考文献哪里找...
  9. ESP32开发之旅——ssd1306 OLED屏的使用
  10. mathtype免费版下载及序列号获取地址