算法 拓扑序列

拓扑序列

定义

是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。 且该序列必须满足下面两个条件: 每个顶点出现且只出现一次。 若存在一条从顶点A 到顶点B 的路径,那么在序列中顶点A 出现在顶点B 的前面。

并不是所有的图都存在拓扑序。有向无环图一定存在拓扑序,有向无环图又被称为拓扑图。

基本概念

入度

一个点有多少条边指向自己

出度

由该点出发的有几条边

应用范围

有向无环图

作用

判断该图中有无环。

形成

只要有一个环,就无法形成拓扑序,因为环上每个点的入度都不为0。

有向无环图一定存在一个拓扑序,有向无环图也被称为拓扑图。

一个有向无环图,一定至少存在一个入度为0的点。

如何求拓扑序

构造算法思路

因为进行一个排序,保证满足拓扑定义。而有向无环图中是一定有一个或多个点入度为0的,这些点只可能在拓朴排序前面,所以以他们中的一个为起点进行排序。

以某点为起始点的边的另一个节点,在序列中只可能在该边起始点后面,由于边与边之间可能会链接,所以为保证拓扑序列的正确性,每次将入度为0的点作为基点进行相关边的探查,当存在边所关联的另一点只有这一条边的时候,该点应该为拓扑序列的下一批点中的一个【上一批可能有多个点度为零】。所以进行拓扑序列的构造应该进行以下操作。

将所有入度为0的点入队列,当队列非空时,每次取出队列头元素top,依次遍历所有以top为起始点的有向边。将对应边的另一点入度减一【表示去掉以t为起始点的这条边】,将这些点中入度为0的点输出并加入队列。此时这些点已然在拓扑序列之中。之后做同样的操作。

所有入度为0的点【没有任何一条边指向该点】都可以作为起点,都可以排在当前最前面的位置。

出队的顺序是拓扑序,拓扑序可能不唯一。

实现

其实就是使用BFS

在使用邻接链表存储边时,记录结束节点的入度。之后将入度为0的入队,然后进行bfs。

每次记录队头后出队,以队头为起点的边的终点的入度减1,看能不能为0,为零入队。以此类推

queue <——所有入度为0的点 将所有入度为0的点入队

//宽搜

while(queue 不空){

t<—每一次取队头

枚举t的所有出边t—>j

删掉t—>j,d[j]--(j的入度减1)

if(d[j]==0){

queue <——j 将j入队

}

}

若存在环,环上所有点的入度都不为0,环上所有点都无法入队。

//主函数
//主函数输入所有边时要更新入度
for (int i = 0;i < m;i++) {int a, b;cin >> a >> b;add(a, b);d[b]++;//更新入度}
//拓扑序函数
bool topsort() {int hh = 0, tt = -1;for (int i = 1;i <= n;i++) {//将所有入度为0的点入队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] == 0) q[++tt] = j;}}return tt == n - 1;//判断是否所有点都进入过队列,如果tt==n-1,说明n个点全部进入过队列
}
//出队的顺序是拓扑序,答案可能不一致

例题——有向图的拓扑序

给定一个n个点m条边的有向图,图中可能存在重边和自环。

请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。

若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

输入格式
第一行包含两个整数n和m

接下来m行,每行包含两个整数x和y,表示存在一条从点x到点y的有向边(x, y)。

输出格式
共一行,如果存在拓扑序列,则输出拓扑序列。

否则输出-1

数据范围

1≤n,m≤10^5

输入样例

3 3

1 2

2 3

1 3

输出样例

1 2 3

代码

#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];//q是队列,d是入度
void add(int a, int b) {e[idx] = b;ne[idx] = h[a];h[a] = idx++;
}
bool topsort() {int hh = 0, tt = -1;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] == 0) q[++tt] = j;}}return tt == n - 1;//判断是否所有点都进入过队列,如果tt==n-1,说明n个点全部进入过队列
}
int main() {cin >> n >> m;memset(h, -1, sizeof h);for (int i = 0;i < m;i++) {int a, b;cin >> a >> b;add(a, b);d[b]++;//更新入度}if (topsort()) {for (int i = 0;i < n;i++)printf("%d ", q[i]);puts("");}else puts("-1");
}

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

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

相关文章

C++标准模板(STL)- 类型支持 (杂项变换,实施当按值传递实参给函数时所进行的类型变换,std::decay)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实…

苹果配件妙控鼠标、键盘、触控板值得入手吗

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 苹果的优质和成功绝…

Linux安装MariaDB数据库

一句命令完成数据库的安装 环境&#xff1a;centos7&#xff0c;可以连接外网 一、安装MariaDB 命令&#xff1a;yum install mariadb mariadb-server -y [rootchensy ~]# yum install mariadb mariadb-server -y Loaded plugins: fastestmirror Repository base is listed m…

STM32存储左右互搏 SPI总线读写FRAM MB85RS16

STM32存储左右互搏 I2C总线读写FRAM MB85RS16 在中低容量存储领域&#xff0c;除了FLASH的使用&#xff0c;&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于FLASH&#xff0c;FRAM写操作时不需要预擦除&#xff0c;所以执行写操作时可以达到更高的速度&#xff0c;其…

40 mysql join 的实现

前言 join 是一个我们经常会使用到的一个 用法 我们这里 看一看各个场景下面的 join 的相关处理 测试数据表如下, 两张测试表, tz_test, tz_test03, 表结构 一致 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(128) DEFAULT NULL,fi…

BGP多跳及BGP4+

一、知识补充 1、BGP4 传统BGP-4只管理IPV4路由信息&#xff0c;对于使用其它网络程协议 (若IPV6等)的应用末给予支持。IETF对BGP-4扩展&#xff0c;提出BGP4&#xff0c;可以提供对IPV6、IPX和MPLS VPN的支持 (简单说: 扩展IPV6协议栈支持)。 2、全互联 在上一篇博文中提…

用C++语言编写的图书馆系统代码,包括图书录入、查询、插入、修改、删除和添加功能

#include <iostream> #include <string> #include <vector> using namespace std; // 定义图书结构体 struct Book { int id; // 图书编号 string name; // 图书名称 int quality; // 图书数量 }; // 定义图书馆类 class Library { private: …

leetcode - 矩阵区域和

1314. 矩阵区域和 - 力扣&#xff08;LeetCode&#xff09; 给你一个 m x n 的矩阵 mat 和一个整数 k &#xff0c;请你返回一个矩阵 answer &#xff0c;其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和&#xff1a; i - k < r < i k, j - k < c …

备忘录模式 rust和java的实现

文章目录 备忘录模式介绍实现javarustrust仓库 备忘录模式 备忘录&#xff08;Memento&#xff09;模式的定义&#xff1a;在不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象之外保存这个状态&#xff0c;以便以后当需要时能将该对象恢复到原先…

【5G PHY】5G NR 如何计算资源块的数量?

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

严蔚敏数据结构p17(2.19)——p18(2.24) (c语言代码实现)

目录 2.19已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试写一高效的算法,删除表中所有值大于 mink 且小于 maxk 的元素(若表中存在这样的元素&#xff09;同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink 和 maxk 是给定的个参变量,它们的值可以和表…

Hdoop学习笔记(HDP)-Part.12 安装HDFS

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

day4 链表(2)

Day4 2023.12.3&#xff08;昨天有事没写&#xff0c;按训练营时间&#xff0c;周天休息&#xff0c;我把第三天的补上&#xff09; 代码随想录 1. 24两两交换链表中的节点 对于交换节点&#xff0c;不仅仅是值得交换&#xff0c;不然就很简单了&#xff0c;我们要交换的是节点…

继阿里云、滴滴、语雀后,腾讯视频也出现重大系统故障

昨晚&#xff0c;许多网友报告称腾讯视频出现了网络故障&#xff0c;具体表现为首页无法加载内容、VIP 用户无法观看会员视频等问题。 针对这一问题&#xff0c;腾讯视频回应称&#xff1a;目前腾讯视频遇到了暂时的技术问题&#xff0c;正在紧急修复中&#xff0c;各项功能正在…

在项目根目录未找到 app.json

这个问题就是我们在编译后的app.json文件找不到&#xff0c;路径出现了问题 首先看dist下我们该文件的路径 所以我们需要将该路径配置到我们project.config.json文件中去 在这里新加下面这行代码就可以了&#xff0c; "miniprogramRoot": "dist/dev/mp-weixi…

C语言扫雷游戏

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、扫雷游戏的分析和设计1.1扫雷游戏的功能说明1.2数据结构的分析1.3文件结构设计 二、扫雷游戏的代码实现总结 前言 详细介绍扫雷游戏的思路和实现过程。 一…

虚拟化逻辑架构:OVS 交换机与端口管理

目录 一、实验 1.OVS 交换机管理 2.OVS端口管理 二、问题 1.KVM下的br0和virbr0有何区别 一、实验 1.OVS 交换机管理 &#xff08;1&#xff09;查看网络信息 lo:本地回环接口 enp0s17 : ubuntu系统识别到的物理网卡 virbr0/br1/virbr0-nic : linux bridge 网桥相关…

基于springboot + vue体育馆使用预约平台

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

自动提交日志脚本(6)浏览器抓包日志提交的数据

主要完成 do_logigdo_write_log 通过python的requests库post数据上传&#xff0c;因为是公司的系统我就展示抓包了&#xff0c;不展示怎么写了。 这边用日志暂存的页面做展示。 步骤 打开对应的页面&#xff0c;再打开浏览器的开发人员工具【一般是按f12】点击暂存按钮&…

【算法思考记录】力扣2134. 最少交换次数来组合所有的 1 II【Python3,滑动窗口】

最少交换次数来组合所有的 1 II - 解题思路与代码分析 题目描述 本题目要求我们找到在一个环形二进制数组中&#xff0c;通过最少的交换次数把所有的 1 聚集在一起的方法。数组的环形特性意味着第一个元素和最后一个元素是相邻的。我们需要考虑数组的这种特殊结构来找到最优解…