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

题解:AtCoder AT_awc0028_d Course Enrollment Order

【题目来源】

AtCoder:D - Course Enrollment Order

【题目描述】

Takahashi is trying to take all \(N\) courses at his university.
高桥正在尝试修读他大学的所有 \(N\) 门课程。

The courses are numbered from \(1\) to \(N\), and each course is taken exactly once. Some courses have prerequisite courses, and in order to take such a course, all of its prerequisite courses must have been completed beforehand. A single course may have multiple prerequisites. Courses with no prerequisites can be taken from the beginning.
课程编号从 \(1\)\(N\),每门课程恰好修读一次。有些课程有先修课程,为了修读这样的课程,其所有先修课程必须已经完成。一门课程可能有多个先修课程。没有先修课程的课程可以从一开始就修读。

There are \(M\) prerequisite relationships given, each in the form: "In order to take course \(B_j\), course \(A_j\) must have been completed first."
给出了 \(M\) 个先修关系,每个关系形式如下:"为了修读课程 \(B_j\),必须先完成课程 \(A_j\)。"

Takahashi takes courses one at a time. At each step, among the courses he has not yet taken whose prerequisites have all been completed (these are called available courses), he selects the one with the smallest number and takes it.
高桥一次修读一门课程。在每一步,在所有尚未修读且其先修课程已全部完成的课程中(这些课程称为可选课程),他选择编号最小的那一门进行修读。

Output the order in which Takahashi takes all the courses.
输出高桥修读所有课程的顺序。

It is guaranteed that there are no contradictions in the prerequisite relationships (i.e., no cycles exist), and that it is always possible to take all courses. Furthermore, the above rule uniquely determines the order of enrollment.
保证先修关系中没有矛盾(即不存在循环),并且始终可以修完所有课程。此外,上述规则唯一确定了选课顺序

【输入】

\(N\) \(M\)
\(A_1\) \(B_1\)
\(A_2\) \(B_2\)
\(\vdots\)
\(A_M\) \(B_M\)

  • The first line contains an integer \(N\) representing the number of courses and an integer \(M\) representing the number of prerequisite relationships, separated by a space.
  • The \(j\)-th of the following \(M\) lines \((1 \leq j \leq M)\) contains integers \(A_j\) and \(B_j\) separated by a space, indicating that course \(A_j\) must be completed before taking course \(B_j\).

【输出】

Output the order in which Takahashi takes the courses on a single line, separated by spaces. That is, output \(N\) integers arranged from left to right in the order they are taken.

【输入样例】

4 3
1 2
3 4
2 4

【输出样例】

1 2 3 4

【核心思想】

  1. 问题分析:给定有向无环图(DAG),需要输出一个拓扑序列,使得序列的字典序最小。普通队列实现的拓扑排序只能保证得到一个合法序列,但无法保证字典序最小。

  2. 算法选择

    • Kahn算法:基于入度的拓扑排序算法
    • 优先队列(最小堆):每次从入度为 \(0\) 的节点中选择编号最小的,保证字典序
  3. 关键步骤

    • 初始化入度数组 \(in[v]\) 和邻接表
    • 将所有入度为 \(0\) 的节点加入优先队列(最小堆)
    • 循环取出队首最小元素 \(u\),加入拓扑序列
    • 遍历该节点的所有出边,减少邻接点 \(v\) 的入度 \(in[v]\)
    • 若邻接点入度变为 \(0\),加入优先队列
    • 最终输出拓扑序列
  4. 时间/空间复杂度

    • 时间复杂度:\(O((N + M) \log N)\),每个节点和边处理一次,优先队列操作 \(O(\log N)\)
    • 空间复杂度:\(O(N + M)\),邻接表、入度数组和队列
  5. 字典序拓扑排序的核心思想

    • 普通队列:先进先出,拓扑序列不唯一
    • 优先队列:每次选择最小可用节点,保证字典序最小
    • 适用于需要最小/最大字典序拓扑序列的场景

【算法标签】

拓扑排序

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005, M = 200005;int n, m;
// 优先队列(最小堆),用于实现字典序最小的拓扑排序
priority_queue<int, vector<int>, greater<int> > q;
// 存储拓扑排序的序列
vector<int> seq;
// 入度数组
int ind[N];
// 邻接表(数组模拟链表)
int h[N], e[M], ne[M], idx;// 添加有向边 a -> b
void add(int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}int main()
{cin >> n >> m;// 初始化邻接表头指针memset(h, -1, sizeof(h));for (int i = 1; i <= m; i++){int a, b;cin >> a >> b;add(a, b);// 增加终点 b 的入度ind[b]++;}// 将所有入度为 0 的顶点加入优先队列for (int i = 1; i <= n; i++){if (ind[i] == 0){q.push(i);}}while (!q.empty()){// 取出当前编号最小的入度为 0 的顶点int u = q.top();q.pop();// 将该顶点加入拓扑序列seq.push_back(u);// 遍历顶点 u 的所有出边for (int i = h[u]; i != -1; i = ne[i]){int j = e[i];// 减少后继顶点的入度ind[j]--;// 如果入度变为 0,则加入优先队列if (ind[j] == 0){q.push(j);}}}// 输出拓扑排序的结果for (int i = 0; i < seq.size(); i++){cout << seq[i] << " ";}cout << endl;return 0;
}

【运行结果】

4 3
1 2
3 4
2 4
1 2 3 4
http://www.jsqmd.com/news/1011323/

相关文章:

  • 掌握AI教材写作技巧!低查重工具助力,轻松打造专属优质教材!
  • 如何用MAA明日方舟助手一键完成全日常任务:终极免费自动化指南
  • 题解:学而思编程 小明的U盘
  • 2026年陕西地区技工院校权威观察:新纪元如何构建“教学-实训-就业”闭环生态 - 品研笔录
  • Mythos:首个可规模化漏洞挖掘的AI安全智能体
  • 飞腾D2000+银河麒麟V10开发笔记:网络编程时获取本机IP的几种方法对比
  • 2026邯郸本地水质检测饮用水检测哪家强?TOP 正规机构榜单 + 联系方式 - 中安检测集团
  • TranslucentTB终极教程:如何快速解决Windows任务栏透明化工具的VCLibs依赖问题
  • CVPR、ICCV、ECCV三大顶会到底怎么选?给计算机视觉研究新手的投稿全攻略
  • 2026怀化厂区电能质量测试评估放心机构 TOP + 实地测评 + 详细地址电话 - 中检检测集团
  • 从‘半选’状态聊起:如何用QSS为PyQt5/PySide2的QCheckBox设计一套专业的UI组件库?
  • 别再看官方文档了!手把手教你为SuperMap GIS项目选对国产服务器和CPU(附避坑清单)
  • 视频转PPT:如何从3小时会议录像中提取出完美演示文稿
  • skill 知识
  • 2026太阳能路灯实力厂家:市政/农村/景区/庭院/小区路灯,匠心品质与亮化工程优选 - 品牌发掘
  • 终极QQ音乐解密指南:3分钟解锁你的加密音乐库
  • dendrogram如何提升销售预测准确率:产品相似性建模实战
  • 2026济南本地水质检测饮用水检测哪家强?TOP 正规机构榜单 + 联系方式 - 中安检测集团
  • Ferret多模态模型:实现像素级UI理解与指哪打哪的视觉-语言对齐
  • 2026贵州厂区电能质量测试评估放心机构 TOP + 实地测评 + 详细地址电话 - 中检检测集团
  • 2026青岛七区三市逸程手表回收指南六大维度测评 - 逸程
  • 广州同城就近选宠攻略!六大门店分区详解,不用跑远就能挑靠谱萌宠 - 润富黄金回收
  • 2026湖北武汉高三复读集训营哪家好 分层教学+心理疏导|复读提分实操指南 - 善良的阿良
  • 用GPT-Builder打造Plotly地理可视化AI助手
  • 别再到处找靶场了!Vulnhub、HackTheBox、Vulhub... 这8个主流渗透测试靶场怎么选?
  • 2026年工业润滑油/液压油/齿轮油/切削液/导热油/长城卓力普力源头厂家品牌推荐:专业润滑与防腐性能深度解析 - 品牌发掘
  • 基于PLC控制的汽车铰链自动压装机虚拟样机设计3124(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • Hitboxer终极指南:专业级键盘重映射与SOCD解决方案
  • 遗传算法工程实战:动态架构、自适应调参与收敛诊断
  • 别急着买新款!聊聊Garmin fēnix 7X Pro的‘小睡检测’和‘光线感应器’到底值不值那1500块差价