拓扑序列及其排序

news2024/11/27 1:27:19

目录

  • 一、拓扑序列及其排序的相关概念
    • 拓扑序列的定义
    • 拓扑序列的性质
    • 出度、入度、度数
    • 拓扑排序
  • 二、拓扑序列及其排序的应用
    • 有向图的拓扑序列
      • 代码实现


一、拓扑序列及其排序的相关概念

拓扑序列的定义

拓扑序列是对一个 有向无环图(DAG)(也称为拓扑图)而言的,有向图的拓扑序列是其顶点的线性排序,使得对每条有向边 (u,v)u 在序列中出现在 v之前。

例如下图:
拓扑序
存在4条边:(1,3)(1,2)(2,4)(2,3)

该图的拓扑序列必须要满足以下两点:

  • 每个顶点只出现一次。
  • 对于图中的任何一条边,起点必须在终点之前。

拓扑序列的性质

  • 对于一个有 n 个顶点的 DAG可能存在多个不同的拓扑序列
  • 如果图中存在环,则不能得到拓扑序列。如果图中不存在环,则至少存在一个拓扑序列。
  • 可以使用广度优先搜索、深度优先搜索等图遍历算法求解拓扑序列。
  • 拓扑序列在很多场景下有应用,比如为工程项目排序建立先后关系、计算程序中任务的执行顺序等。
  • 拓扑序列可以用于检测图中是否存在环。如果可以成功生成拓扑序列,说明图中没有环,反之则说明有环。
  • 对于一个DAG,可以根据拓扑序列将其转化为等价的序列图。

出度、入度、度数

出度(Out-degree):对于一个图中的某个顶点,出度表示从该顶点指向其他顶点的边的数量。它描述了从该顶点发散出去的连接数。

入度(In-degree):对于一个图中的某个顶点,入度表示指向该顶点的边的数量。它描述了进入该顶点的连接数。

度数(Degree):对于一个图中的某个顶点,度数等于其出度与入度的和。它描述了与该顶点相关的边的总数。

在这里插入图片描述


拓扑排序

①从图中选择一个入度为0的顶点,并输出该顶点;
②从图中删除该顶点及其相关联的有向边,调整被删除有向边的终点的入度(入度减1);
③重复①和②;
④直到所有顶点均被输出,拓扑序列完成;否则,无拓扑序列。

如下图所示:
在这里插入图片描述


二、拓扑序列及其排序的应用

有向图的拓扑序列

题目描述:
给定一个 n n n 个点 m m m 条边的有向图,点的编号是 1 1 1 n n n,图中可能存在重边和自环。

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

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

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

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

输出格式:
共一行,如果存在拓扑序列,则输出任意一个合法的拓扑序列即可。否则输出−1

数据范围:
1 ≤ n , m ≤ 1 0 5 1≤n,m≤10^5 1n,m105

输入样例:

3 3
1 2
2 3
1 3

输出样例:

1 2 3

代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<queue>

using namespace std;

const int N = 1e5 + 10;
int h[N], e[N * 2], ne[N * 2], idx, n, m;
int d[N];
vector<int> path;

void add(int a, int b)
{
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx++;
}
bool topsort()
{
	queue<int> q;
	for (int i = 1; i <= n; ++i)
	{
		if (!d[i])
		{
			q.push(i);
			path.push_back(i);
		}
	}
	
	while (q.size())
	{
		auto t = q.front();
		q.pop();
		for (int i = h[t]; i != -1; i = ne[i])
		{
			int j = e[i];
			if (!(--d[j]))
			{
				path.push_back(j);
				q.push(j);
			}
		}
	}
	return path.size() == n;
}
int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
	memset(h, -1, sizeof h);

	cin >> n >> m;
	for (int i = 1; i <= m; ++i)
	{
		int a, b;
		cin >> a >> b;
		add(a, b);
		d[b]++;
	}
	if (!topsort()) cout << "-1" << endl;
	else
	{
		for (auto u : path) cout << u << ' ';
		cout << endl;
	}
	return 0;
}

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

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

相关文章

SpringBoot整合gRPC -- 简单明了

项目结构 pom引入(parent中引入即可) <properties><net-devh-grpc.version>2.14.0.RELEASE</net-devh-grpc.version><os-maven-plugin.version>1.6.0</os-maven-plugin.version><protobuf-maven-plugin.version>0.5.1</protobuf-mave…

Python绘制一个圆

代码 import matplotlib.pyplot as plt import numpy as npradius 10 # 半径的长度 center np.array([0,0]) # 圆心的坐标 t np.linspace(0, 2 * np.pi, 100) x center[0] radius * np.cos(t) y center[1] radius * np.sin(t)plt.figure(figsize(5,5)) plt.plot(x,y) p…

C# Modbus通信从入门到精通(5)——Modbus RTU(0x03功能码)

1、03(0x03)读保持寄存器 使用该功能码能从远程地址中读取1到125个保持寄存器的值,每个保持寄存器都占两个字节,读取的保持寄存器数量由主站读取时指定。 2、发送报文格式 更详细的格式如下: 从站地址+功能码+起始地址高位+起始地址低位+寄存器数量高位+寄存器数量低位+…

Redis进阶源码 - 主流程源码

redis底层是C语言编写的一个可执行程序&#xff0c;主方法为server.c 中main方法 主要包括&#xff1a;从初始化 到 EventLoop整个流程源码内容介绍 画的分析图太大了&#xff0c;需要的直接下载看吧.....想提醒大家的是&#xff0c;看源码时一定要带着目标去看&#xff0c;比…

《微服务架构设计模式》第十一章 开发面向生产环境的微服务应用

内容总结自《微服务架构设计模式》 开发面向生产环境的微服务应用 一、开发安全的服务1、安全性概述2、单体应用安全性3、微服务应用安全性 二、如何使用外部化配置模式三、如何使用可观测性模式四、使用微服务基底模式开发服务1、使用微服务基地2、从微服务到服务网格 五、总结…

前端开发面试题及答案整理(合集)

前端开发面试题及答案 1、对Web标准以及W3C的理解与认识? 答&#xff1a;标签闭合、标签小写、不乱嵌套、提高搜索机器人搜索几率、使用外链CSS和JS脚本、结构行为表现的分离、文件下载与页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组…

2023年NOC决赛-加码未来编程赛项决赛模拟题-Python模拟题--卷1

第一题: 小码君在和朋友们玩密室逃脱。他们被困在一个封闭的房间中,只有破解密码,才能逃出密室。密码提示如下:“将 1 到 100 以内,能被 7 整除的数的个数以及这些数累加起来的和拼在一起即是打开房门的密码” 。请帮小码君算出密码。(注:只需显示表示结果的纯数字,不…

动手学深度学习——softmax回归的从零开始(代码详解)

目录 1. softmax回归的从零开始实现1.1 初始化模型参数1.2 定义softmax操作1.3 定义模型1.4 定义损失函数1.5 分类精度1.6 训练1.7 预测1.8 小结 1. softmax回归的从零开始实现 引入Fashion-MNIST数据集&#xff0c; 并设置数据迭代器的批量大小为256。 import torch from IP…

快速实现单数据表编辑

目录 1 简介 2 准备电子表格 3 初始化 4 根据电子表格生成数据库表并导入数据 5 使刚创建的表显示在待编辑列表中 6 开始编辑单表 7 一段代码用于实现中文字段名、调整列宽、只读字段、隐藏字段 1 简介 单数据表是最容易实现的表。由于不需要从零开始一个一个地增加字段…

pwm呼吸灯

文章目录 一、呼吸灯二、代码实现三、引脚分配 一、呼吸灯 呼吸灯是指灯光在微电脑的控制之下完成由亮到暗的逐渐变化&#xff0c;使用开发板上的四个led灯实现1s间隔的呼吸灯。 二、代码实现 c module pwm_led( input clk ,input rst_n ,output reg [3:0] led ); …

当你输入URL并按下回车后,发生了什么?

大概发生了八步的事情&#xff1a; URL解析->DNS解析->服务器建立连接->发送HTTP请求->服务器处理请求->服务器响应->接收和渲染页面->关闭连接 URL解析 URL&#xff0c;统一资源定位符&#xff0c;是用来表示从互联网上得到的资源位置和访问这些资源的…

ARM DynamIQ简介

DynamIQ是ARM一个新的底层solution&#xff0c;用于连接在一个芯片上的不同core&#xff0c;将多个core连接起来。 有了DynamIQ&#xff0c;我们可以将不同类型的core放到一个cluster中。比如&#xff0c;将性能高的core&#xff0c;和功耗低的core放进一个cluster&#xff0c;…

【uni-app】常用图标、头像汇总

在做小程序的时候&#xff0c;有时候需要各种图标和头像素材&#xff0c;而百度一堆基本都是收费的。所以&#xff0c;整理一些免费好用的图标&#xff0c;头像库&#xff1a; 1、iconfont-阿里巴巴矢量图标库 基本上常用的矢量图标&#xff0c;在这儿都有&#xff0c;而且可…

基于SSM框架的汽车在线销售系统设计与实现

博主介绍&#xff1a;专注于Java技术领域和毕业项目实战。专注于计算机毕设开发、定制、文档编写指导等&#xff0c;对软件开发具有浓厚的兴趣&#xff0c;工作之余喜欢钻研技术&#xff0c;关注IT技术的发展趋势&#xff0c;感谢大家的关注与支持。 技术交流和部署相关看文章…

Eureka的使用手册

一、导入依赖&#xff08;服务端和客户端导入的依赖不一样&#xff09; 服务端&#xff1a; <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependenc…

『数据增强』yolov5 数据增强 与 红外数据增强

目录 yolov5 数据增强 Mosaic Copy paste Random affine MixUp Albumentations Augment HSV(Hue, Saturation,Value) Random horizontal flip 红外数据增强 红外图像的缺点 红外成像技术的特点 红外图像增强经…

常用电子元器件检测方法与经验

电子元器件检测是电子工程师和技术人员工作中不可或缺的一部分。在电子元器件制造和使用过程中&#xff0c;需要对元器件进行检测&#xff0c;以确保其质量和性能符合要求。在本文中&#xff0c;我们将介绍常用的电子元器件检测方法和经验&#xff0c;以帮助读者更好地了解和掌…

redux之reducer 为什么必须是纯函数?

在一个应用中&#xff0c;所有的 state 都是以一个对象树的形式存在一个单一的 store 中&#xff0c;唯一改变 state 的办法就是触发 action&#xff0c;而 reducer 就是用来编写专门的函数决定每个 action 如何改变应用的 state 。 在 Redux store 中保存了 reducer 返回的 这…

make/makefile的使用

make/makefile 文章目录 make/makefile初步认识makefile的工作流程依赖关系和依赖方法make的使用 总结 make是一个命令&#xff0c;是一个解释makefile中指令的命令工具&#xff0c;makefile是一个文件&#xff0c;当前目录下的文件&#xff0c;两者搭配使用&#xff0c;完成项…