数据结构--拓扑排序

news/2024/11/18 4:33:55/

数据结构–拓扑排序

AOV⽹

A O V ⽹ \color{red}AOV⽹ AOV(Activity On Vertex NetWork,⽤顶点表示活动的⽹):
D A G 图 \color{red}DAG图 DAG(有向⽆环图)表示⼀个⼯程。顶点表示活动,有向边 < V i , V j > <V_i, V_j> <Vi,Vj>表示活动Vi必须先于活动 V j V_j Vj进⾏

注:如果图中存在环路就不是 A O V 网 \color{red}注:如果图中存在环路就不是AOV网 注:如果图中存在环路就不是AOV

DAG图是指有向无环图(Directed Acyclic Graph),是一种有向图的特殊形式。它由一些有向边连接的节点组成,并且不存在任何形式的环。换句话说,从任何一个节点出发,沿着有向边的方向无法经过一系列的节点再回到原始节点。DAG图常用于表示一些具有依赖关系的任务或事件,其中每个节点表示一个任务或事件,有向边表示任务或事件之间的依赖关系。DAG图在计算机科学和工程中有广泛的应用,例如任务调度、编译器优化、数据流分析等领域。

拓扑排序

拓扑排序 \color{red}拓扑排序 拓扑排序:在图论中,由⼀个 有向⽆环图 \color{red}有向⽆环图 有向环图的顶点组成的序列,当且仅当满⾜下列条件时,称为该图的⼀个拓扑排序:
① 每个顶点出现且只出现⼀次。
② 若顶点A在序列中排在顶点B的前⾯,则在图中不存在从顶点B到顶点A的路径。或定义为:拓扑排序是对有向⽆环图的顶点的⼀种排序,它使得若存在⼀条从顶点A到顶点B的路径,则在排序中顶点B出现在顶点A的后⾯。每个AOV⽹都有⼀个或多个拓扑排序序列。

上图其中一个拓扑排序:

拓扑排序的实现:

① 从AOV⽹中选择⼀个没有前驱的顶点并输出。
② 从⽹中删除该顶点和所有以它为起点的有向边。
③ 重复①和②直到当前的AOV⽹为空或当前⽹中不存在⽆前驱的顶点为⽌。

注:拓扑排序序列可能有多个 \color{red}注:拓扑排序序列可能有多个 注:拓扑排序序列可能有多个

拓扑排序代码实现

王道书上代码

个人code

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int n, m;
int h[N], e[N], ne[N], idx;
int q[N], d[N];
void add(int a, int b)
{e[idx] = b;ne[idx] = h[a];h[a] = idx++;
}
bool topsort()
{int tt = -1, hh = 0;for(int i = 1; i <= n; i++)if(!d[i])q[++tt] = i;while(hh <= tt){int t = q[hh++];for(int i = h[t]; i != -1; i = ne[i]){int j = e[i];d[j]--;if(!d[j]) q[++tt] = j;}}return tt == n - 1;
}
int main()
{cin >> n >> m;memset(h, -1, sizeof(h));for(int i = 0; i < n; i++){int a, b;cin >> a >> b;add(a, b);d[b]++;}if(topsort()){for(int i = 0; i < n; i++)cout << q[i] << ' ';cout << endl;}else cout << "-1" << endl;return 0;
}

判断是否存在拓扑序

时间复杂度 O(n + m), n 表示点数,m表示边数
bool topsort()
{int hh = 0, tt = -1;// d[i] 存储点i的⼊度for (int i = 1; i <= n; i ++ )if (!d[i])q[ ++ tt] = i;while (hh <= tt){int t = q[hh ++ ];for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (-- d[j] == 0)q[ ++ tt] = j;}}// 如果所有点都⼊队了,说明存在拓扑序列;否则不存在拓扑序列。return tt == n - 1;
}

逆拓扑排序

对⼀个AOV⽹,如果采⽤下列步骤进⾏排序,则称之为 逆拓扑排序 \color{red}逆拓扑排序 逆拓扑排序
① 从AOV⽹中选择⼀个没有后继( 出度为 0 \color{red}出度为0 出度为0)的顶点并输出。
② 从⽹中删除该顶点和所有以它为终点的有向边。
③ 重复①和②直到当前的AOV⽹为空。

其中一个逆拓扑排序

逆拓扑排序代码实现

逆拓扑排序的实现(DFS算法)

DFS判断是否有环:

int vis[N], cnt; // timestamp
int per[N];
bool cyc[N];// 标记
void dfs(int u) //找环 & 标记环
{vis[u] = ++cnt;for (auto v : g[u]){if (per[u] == v)continue;if (!vis[v]){per[v] = u;dfs(v);}else if (vis[u] > vis[v]){for (int i = u; i != v; i = per[i])cyc[i] = true;cyc[v] = true;}}
}

如果单纯判断是否有环,只需要引进父结点(fa)
dfs(u,fa)
如果 u == fa 则存在环

知识点回顾与重要考点


http://www.ppmy.cn/news/1041530.html

相关文章

k8s容器加入host解析字段

一、通过edit或path来修改 kubectl edit deploy /xxxxx. x-n cattle-system xxxxx为你的资源对象名称 二、添加字段 三、code hostAliases:- hostnames:- www.rancher.localip: 10.10.2.180

css3阴影效果

首先效果如下&#xff1a; 阴影效果完整代码如下 上面的动态图是没有加transition的&#xff0c;为了美观加上了一个 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&…

面试题-React(二):React中的虚拟DOM是什么?

一、什么是虚拟DOM&#xff1f; 虚拟DOM是React的核心概念之一&#xff0c;它是一个轻量级的JavaScript对象树&#xff0c;用于表示真实DOM的状态。在React中&#xff0c;当数据发生变化时&#xff0c;首先会在虚拟DOM上执行DOM更新&#xff0c;而不是直接操作真实DOM。然后&a…

虹科干货|一份选择微服务监控工具的指北

毋庸置疑&#xff0c;监控是管理任何微服务架构的一个关键方面。但是如何为业务选择最佳的微服务监控工具呢&#xff1f;有哪些微服务监控工具&#xff1f;这些工具有什么功能&#xff1f;这里一份参考指北供你参阅。 监控您的期望 监控哪些内容&#xff1f; 在选择工具之前&a…

两个内网之间的linux服务器如何互相登录?快解析内网穿透

如果两个内网之间的linux服务器需要互相登录&#xff0c;或需要互相访问内网某个端口&#xff0c;担忧没有公网IP&#xff0c;可以使用的方法有 ngrok, 但并不方便&#xff0c;我们只需两条 SSH 命令即可。 SSH 内网端口转发实战SSH 内网端口转发实战 先给出本文主角&…

Git常见操作

一、全局配置命令 配置级别&#xff1a; –local&#xff08;默认&#xff0c;高级优先&#xff09;&#xff1a;只影响本地仓库 –global(中优先级)&#xff1a;只影响所有当前用户的git仓库 –system&#xff08;低优先级&#xff09;&#xff1a;影响到全系统的git仓库 1…

openEuler离线安装nginx、openEuler安装nginx、openEuler配置nginx

官方文档有在线安装很快,但实际生产,有不少要部署到内网、局域网中,三种方式一起介绍下: 第一种:离线安装 准备离线环境: 在一台联网的机器上,使用以下命令下载 Nginx 及其依赖库的 RPM 包: mkdir nginx-offline-install cd nginx-offline-install yumdownloader -…

怎么把pdf压缩到5m以内?压缩办法非常多

怎么把pdf压缩到5m以内&#xff1f;PDF文件是我们办公过程中较为常用的文件格式&#xff0c;PDF文件所包含的内容通常较多&#xff0c;比如文本、图像以及音视频等等。这样的话&#xff0c;PDF文件占用内存也较大。如果需要对PDF文件进行使用、传输、分享等的话&#xff0c;可能…