拓扑排序[讲课留档]

拓扑排序

拓扑排序要解决的问题是给一个有向无环图的所有节点排序

即在 A O E AOE AOE网中找关键路径

前置芝士!
  • 有向图:有向图中的每一个边都是有向边,即其中的每一个元素都是有序二元组。在一条有向边 ( u , v ) (u,v) (u,v)中,称 u u u v v v直接前驱 v v v u u u直接后继
  • 有向无环图 ( D i r e c t e d A c y c l i c G r a p h ) (Directed\ Acyclic\ Graph) (Directed Acyclic Graph):没有有向环,但不保证原图变成无向图时无环。


  • D A G DAG DAG的性质:能拓扑的图一定是 D A G DAG DAG D A G DAG DAG一定能拓扑。( A O E 和 A O V AOE和AOV AOEAOV网都是 D A G DAG DAG)
  • 度:顶点 v v v的度数是与 v v v关联的边数。有向图中没有度的概念。
  • 入度、出度:入度是指以该顶点为终点的有向边数量;顶点的出度是指以顶点为起点的有向边数量。无向图中没有出入度的概念。
举个例子!

我们可以拿大学排课的例子来描述这个过程,比如学习大学课程中有:程序设计,算法语言,高等数学,离散数学,编译技术,数据结构,数据库系统等。当我们想要学习数据结构的时候,就必须先学会离散数学编译技术算法语言

这些课程就相当于几个顶点 u u u, 顶点之间的有向边 ( u , v ) (u,v) (u,v)就相当于学习课程的顺序。教务处安排这些课程,使得在逻辑关系符合的情况下排出课表,就是拓扑排序的过程。

但是如果某一天排课的老师打瞌睡了,说想要学习数据结构,还得先学操作系统,而操作系统的前置课程又是数据结构,那么到底应该先学哪一个(不考虑同时学习的情况)?在这里数据结构操作系统间就出现了一个环,显然你现在没办法弄清楚你需要先学什么了,于是你也没办法进行拓扑排序了。

拓扑排序即,在一个 D A G DAG DAG(有向无环图)中,我们将图中的顶点以线性方式进行排序,使得对于任何的顶点u到v的有向边 ( u , v ) (u,v) (u,v), 都可以有 u u u v v v的前面。

严谨来说,给定一个 D A G DAG DAG,如果从 i i i j j j有边,则认为 j j j依赖于 i i i。如果 i i i j j j有路径( i i i可达 j j j ),则称 j j j间接依赖 i i i。拓扑排序的目标是将所有节点排序,使得排在前面的节点不能依赖于排在后面的节点

理论存在!
  1. 从图中选择一个入度为零的点。
  2. 记录该顶点,从图中删除此顶点及其所有的出边。

重复上面两步,直到所有顶点都输出,拓扑排序完成,此时我们可以得到一个点的出队顺序(遍历顺序)这个序列叫拓扑序;或者图中不存在入度为零的点,此时说明图是有环图,拓扑排序无法完成。

拓扑排序需要遍历整张图,假设该图为 G ( V , E ) G(V,E) G(V,E),获得拓扑序的时间复杂度大约是O(V+E)

实践开始!
void topu_sort() {queue<int>q;for (int i = 1; i <= n; ++i) {if (!d[i])q.push(i);}while (!q.empty()) {int now = q.front();q.pop();ans.push_back(now);int len = vec[now].size();for (int i = 0; i < len; ++i) {int to = vec[now][i];d[to]--;if (!d[to]) q.push(to);}}/*for(auto x:vec[now]){d[x]--;if(!d[x]) q.push(x);}*/
}
例题

拓扑模板:B3644 【模板】拓扑排序 / 家谱树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 150;
int n;
vector<int> e[N];
int d[N];
vector<int> ans;void topu() {queue<int> q;for (int i = 1; i <= n; ++i) {if (d[i] == 0) q.push(i);}while (!q.empty()) {int now = q.front();q.pop();ans.push_back(now);for (auto x: e[now]) {d[x]--;if (d[x] == 0) q.push(x);}}
}int main() {cin >> n;for (int i = 1; i <= n; ++i) {int x;while (cin >> x) {if (x == 0) break;d[x]++;e[i].push_back(x);}}topu();for (auto x: ans) {cout << x << " ";}cout << '\n';return 0;
}
提高
拓扑构造:Problem - E - Codeforces
解析:

先忽略所有输入的无向边(但是不忽略点),对当前的有向图拓扑排序,如果给定的有向图中已经不是 D A G DAG DAG显然是一定不成立也无法构造的;如果当前的图是 D A G DAG DAG,那么拓扑完我们可以得到一个或多个拓扑序,每个拓扑序都是线性的,这也代表当选定一个拓扑序,在所有点中任选两个点,他们一定有已知确定先后顺序,我们按照这样的顺序去构造,建边(每次令拓扑序靠前的指向靠后的)即可保证不会出现拓扑序靠前的点依赖于靠后的点,则不会出现有向环。

AC代码:
pii ans[N];
vector<int>e[N];
int d[N];
int n,m,order=0;
int ord[N];bool topu(){queue<int>q;for(int i=1;i<=n;++i){if(!d[i]){q.push(i);}}while(!q.empty()){int t=q.front();q.pop();ord[t]=++order;for(auto x:e[t]){d[x]--;if(!d[x])q.push(x);}}if(order!=n)return 0;return 1;
}void work() {cin>>n>>m;int tot=0;order=0;for(int i=1;i<=n;++i){d[i]=0;e[i].clear();ans[i].fi=ans[i].se=0;}for(int i=1;i<=m;++i){int z,u,v;cin>>z>>u>>v;if(z){e[u].pb(v);d[v]++;}else{ans[++tot].fi=u;ans[tot].se=v;}}if(!topu()){cout<<"No\n";return;}cout<<"Yes\n";for(int i=1;i<=tot;++i){if(ord[ans[i].fi]>ord[ans[i].se])swap(ans[i].se,ans[i].fi);cout<<ans[i].fi<<" "<<ans[i].se<<'\n';}for(int i=1;i<=n;++i){if(e[i].size()){for(auto x:e[i]){cout<<i<<" "<<x<<'\n';}}}
}

课后练习:P1347 排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

总结:

拓扑排序是图论中非常基础的算法,大多时候作为工具,或者一些进阶算法的预处理内容,非常简单,同时需要熟练掌握。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/39027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT 官方发布桌面端,向所有用户免费开放

Open AI 官方已经发布了适用于 macOS 的 ChatGPT 桌面端应用。 此前&#xff0c;该应用一直处于测试阶段&#xff0c;仅 Plus 付费订阅用户可以使用。 目前已面向所有用户开放&#xff0c;所有 Mac 用户均可免费下载使用。 我们可以访问官网下载安装包&#xff1a;https://op…

2024 年江西省研究生数学建模竞赛题目 B题投标中的竞争策略问题--完整思路、代码结果分享(仅供学习)

招投标问题是企业运营过程中必须面对的基本问题之一。现有的招投标平台有国家级的&#xff0c;也有地方性的。在招投标过程中&#xff0c;企业需要全面了解招标公告中的相关信息&#xff0c;在遵守招投标各种规范和制度的基础上&#xff0c;选择有效的竞争策略和技巧&#xff0…

基于JSP技术的校园餐厅管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果您对校园餐厅管理系统感兴趣或有相关需求&#xff0c;欢迎随时联系我。我的联系方式在文末&#xff0c;期待与您交流&#xff01; 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#x…

QT的编译过程

qmake -project 用于从源代码生成项目文件&#xff0c;qmake 用于从项目文件生成 Makefile&#xff0c;而 make 用于根据 Makefile 构建项目。 详细解释&#xff1a; qmake -project 这个命令用于从源代码目录生成一个初始的 Qt 项目文件&#xff08;.pro 文件&#xff09;。它…

Keil5中:出现:failed to execute ‘...\ARMCC\bin\ArmCC‘

点三个点&#xff0c;去自己的磁盘找自己的ARM\ARMCC\bin

深入解析:计算机系统总线全方位解读

在计算机组成原理中&#xff0c;总线系统是连接计算机各个部件的重要通道。本文将详细介绍系统总线的基本概念、分类、特性及性能指标、结构和控制方式。希望通过本文的讲解&#xff0c;能够帮助基础小白更好地理解计算机系统总线的工作原理。 系统总线 (System Bus) 系统总线…

selenium 简介以及 selenium 环境配置

文章目录 一、初识 selenium1.selenium 简介2.selenium 三大组件3.selenium工作过程和原理4.selenium自动化测试流程5.selenium优点 二、自动化测试1.UI自动化本质2.UI自动化的前提3.适用场景4.UI自动化的原则5.UI自动化的覆盖率 三、selenium 环境配置 一、初识 selenium 1.s…

单点登录demo

gitee.com 搜索xxl(许雪里) 的sso 操作demo 完整流程图

什么是应用安全态势管理 (ASPM):综合指南

软件开发在不断发展&#xff0c;应用程序安全也必须随之发展。 传统的应用程序安全解决方案无法跟上当今开发人员的工作方式或攻击者的工作方式。 我们需要一种新的应用程序安全方法&#xff0c;而ASPM在该方法中发挥着关键作用。 什么是 ASPM&#xff1f; 应用程序安全…

配电智能网关赋能电力系统智能化运行维护

随着智能电网和物联网技术的不断发展&#xff0c;两者之间的融合应用成为电力行业的重要趋势。配电智能网关作为连接两者的关键设备&#xff0c;在智能电网的物联网应用中发挥着重要作用。 配电智能网关能够实现对电力系统的实时监控、数据采集、远程控制等功能&#xff0c;为…

已解决org.omg.CORBA.portable.RemarshalException:在CORBA中需要重新编组的正确解决方法,亲测有效!!!

已解决org.omg.CORBA.portable.RemarshalException&#xff1a;在CORBA中需要重新编组的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 服务器端代码 客户端代码 报错原因 解决思路 解决方法 1. 检查网络连接 …

力扣:LCR 024. 反转链表(Java)

目录 题目描述&#xff1a;示例 1&#xff1a;示例 2&#xff1a;代码实现&#xff1a; 题目描述&#xff1a; 给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链表的头节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#x…

Xinstall智能安装页面:一键唤起App,提升用户体验

在移动互联网时代&#xff0c;App已经成为我们日常生活中不可或缺的一部分。然而&#xff0c;随着App数量的不断增加&#xff0c;用户面临着越来越多的选择&#xff0c;如何快速、便捷地安装并打开App成为了用户的一大痛点。针对这一问题&#xff0c;Xinstall凭借其强大的技术实…

计组_程序的机器级代码表示

2024.06.13&#xff1a;计算机组成原理程序的机器级代码表示 第15节 程序的机器级代码表示 5.1 x86的汇编指令格式5.2 常用指令 眼熟最基础的汇编语法和助记符即可 5.1 x86的汇编指令格式 5.2 常用指令

DeepMind的新论文,长上下文的大语言模型能否取代RAG或者SQL这样的传统技术呢?

长上下文大型语言模型&#xff08;LCLLMs&#xff09;确实引起了一些关注。这类模型可能使某些任务的解决更加高效。例如理论上可以用来对整本书进行总结。有人认为&#xff0c;LCLLMs不需要像RAG这样的外部工具&#xff0c;这有助于优化并避免级联错误。但是也有许多人对此持怀…

WPF对象样式

基本样式设置 Style 设置指定对象的属性 属性&#xff1a; TargetType 引用在哪个类型上面&#xff0c;例如Button、Textblock。。 如果在控件对象里面设置Style&#xff0c;则TargetType必须指定当前控件名 只在作用域里面有效果&#xff0c;其他的相同控件没有影响&…

统一的可观察性和安全性如何增强你的业务?

作者&#xff1a;来自 Elastic Michael Calizo 利用人工智能、异常检测和增强攻击发现功能&#xff0c;在一个平台上增强组织的可观察性和安全性能力 当今数字环境中的组织越来越关注服务可用性&#xff0c;并保护其软件免受恶意篡改和攻击。传统的安全和可观察性工具通常以孤…

【React】上传文章封面基础实现

<Form.Item label"封面"><Form.Item name"type"><Radio.Group onChange{onTypeChange}><Radio value{1}>单图</Radio><Radio value{3}>三图</Radio><Radio value{0}>无图</Radio></Radio.Group&…

react 自定义 年-月-日 组件,单独选择年、月、日,并且产生联动

自定义 年-月-日 组件 code import { useState } from react function Year_Month_Date() {const [yearList, setYearList] useState([])const [monthList, setMonthList] useState([])const [dateList, setDateList] useState([])const [currentYear, setCurrentYear] u…

javaweb(四)——过滤器与监听器

文章目录 过滤器Filter基本概念滤波器的分类: 时域和频域表示滤波器类型1. 低通滤波器(Low-Pass Filter)2. 高通滤波器(High-Pass Filter)3. 带通滤波器(Band-Pass Filter)4. 带阻滤波器(Band-Stop Filter) 滤波器参数1. 通带频率(Passband Frequency)2. 截止频率(Cutoff Frequ…