当前位置: 首页 > article >正文

题解 洛谷 Luogu P1113 杂务 图论 BFS C++

题目

传送门

P1113 杂务 - 洛谷 | 计算机科学教育新生态https://www.luogu.com.cn/problem/P1113

思路

从工作之间的指向性关系不难看出这是基于有向图的问题

边从前置工作通向后置工作,表示完成了前置任务后才能完成后置工作

再模拟这个过程,可以发现这个过程非常像搜索,且更像 BFS

前置工作少的大致在更先搜到的层,前置工作多的大致在更后搜到的层

设 dist[i] 为从开始搜索一直到完成工作 i 所需的时间

t[i] 为完成工作 i 本身需要的时间,若 x 通向 y,则 dist[y] = dist[x] + t[y]

dist[i] 的最大值就是所求答案

但这和一般的 BFS 又不一样

以输入样例为例,2 为队头时,不能直接入队 2 通向的 5,因为 4 也通向 5

入队条件

那我们不禁要想,什么时候才能入队 5 呢?

必须完成所有前置工作才能入队 5

即当队头 x 通向 5 且 x 是 5 的最后一个前置工作时,才能入队 5

维护前置工作信息

我们又怎么知道 x 是不是 5 的最后一个前置工作呢?

额外维护一个数组 from[i],表示通向 i 的节点,也就是 i 的前置工作

对于输入样例,from[5] = { 2,4 },队头为 2 时从 from[5] 中删掉 2

队头为 4 时发现 4 是 5 的最后一个前置工作了,那么此时就可以入队 5 了

Dist[i] 计算

dist[5] 又怎么计算呢?

显然是所有通向 5 的节点的 dist 值的最大值再加上 t[5],即 dist[2]、dist[4] 的最大值再加上 t[5]

搞清楚以上问题后,就可以愉快地写 BFS 了

代码

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
const int N = 10005;
vector<int> from[N], to[N]; //from 存前置工作,to 存后置工作
int n, t[N], dist[N], q[N], head, tail = -1, ans;
void BFS()
{
    while (head <= tail)
    {
        int x = q[head++];
        for (auto X : to[x]) //小 x 是出发点 (前置工作),大 X 是到达点 (后置工作)
        {
            dist[X] = max(dist[X], dist[x] + t[X]); //dist[X] 是 dist[x] 的最大值加上 t[X]
            ans = max(ans, dist[X]);
            if (from[X].size() == 1) q[++tail] = X; //x 是 X 的最后一个前置工作,那么可以入队 X
            from[X].erase(find(from[X].begin(), from[X].end(), x)); //完成了前置工作 x,将 x 从 X 的前置任务列表中删掉
        }
    }
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d%d", &t[i], &t[i]);
        int From;
        while (scanf("%d", &From) && From)
            from[i].push_back(From), to[From].push_back(i); //建图
        if (from[i].empty()) //没有前置工作的工作,是搜索的起点,入队。且其 dist 值要更新成完成该工作本身需要的时间
            q[++tail] = i, dist[i] = t[i];
    }
    BFS();
    printf("%d", ans);
    return 0;
}

http://www.kler.cn/a/520240.html

相关文章:

  • WPF基础 | WPF 布局系统深度剖析:从 Grid 到 StackPanel
  • 2025_1_26 c++中关于构造和析构的顺序
  • Qt监控系统辅屏预览/可以同时打开4个屏幕预览/支持5x64通道预览/onvif和rtsp接入/性能好
  • [操作系统] 进程地址空间管理
  • Android - 通过Logcat Manager简单获取Android手机的Log
  • kafka-保姆级配置说明(broker)
  • 计算机网络之链路层
  • CommonAPI学习笔记-1
  • 【Oracle篇】使用Hint对优化器的执行计划进行干预(含单表、多表、查询块、声明四大类Hint干预)
  • 牛客训练营(一)补题
  • 【2025AI发展预测】2.2025的风口与发展,我们如何主动拥抱这一浪潮
  • 可见光通信代码仿真
  • 狗狗能吃萝卜吗?
  • vim可视化模式的进阶操作
  • C# 类(Class)
  • SOME/IP--协议英文原文讲解1
  • 深度解析:基于Vue 3的教育管理系统架构设计与优化实践
  • 【论文阅读笔记】“万字”关于深度学习的图像和视频阴影检测、去除和生成的综述笔记 | 2024.9.3
  • 【趋势】《2024—2026金融科技十大趋势预测》一览
  • 【学术会议-第五届机械设计与仿真国际学术会议(MDS 2025) 】前端开发:技术与艺术的完美融合
  • Kiwi 安卓浏览器本月停止维护,扩展功能迁移至 Edge Canary
  • 基于SpringBoot的在线众筹网的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • Linux 内核学习(5) --- Linux 内核底半部机制
  • 微信小程序-点餐(美食屋)02开发实践
  • 基于DNN深度神经网络的OFDM+QPSK信号检测与误码率matlab仿真
  • 9.5 GPT Builder 快速入门:如何使用 GPT 构建自定义应用