拓扑排序的实现_TopoSort

go语言:实现卡恩拓扑algorithm topo算法(附完整源码) 阅读详情

拓扑排序是求一个AOV网(顶点代表活动, 各条边表示活动之间的领先关系的有向图)中各活动的一个拓扑序列的运算, 可用于测试AOV

网络的可行性.

整个算法包括三步:

1.计算每个顶点的入度, 存入InDegree数组中.

2.检查InDegree数组中顶点的入度, 将入度为零的顶点进栈.

3.不断从栈中弹出入度为0的顶点并输出, 并将该顶点为尾的所有邻接点的入度减1, 若此时某个邻接点的入度为0, 便领其进栈. 重复步骤

3, 直到栈为空时为止. 此时, 或者所有顶点都已列出, 或者因图中包含有向回路, 顶点未能全部列出.

实现代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
#include "stack"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
#include "string"
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
enum ResultCode { Underflow, Overflow, Success, Duplicate, NotPresent, Failure, HasCycle };
template <class T>
struct ENode
{
	ENode() { nxtArc = NULL; }
	ENode(int vertex, T weight, ENode *nxt) {
		adjVex = vertex;
		w = weight;
		nxtArc = nxt;
	}
	int adjVex;
	T w;
	ENode *nxtArc;
	/* data */
};
template <class T>
class Graph
{
public:
	virtual ~Graph() {}
	virtual ResultCode Insert(int u, int v, T &w) = 0;
	virtual ResultCode Remove(int u, int v) = 0;
	virtual bool Exist(int u, int v) const = 0;
	/* data */
};
template <class T>
class LGraph: public Graph<T>
{
public:
	LGraph(int mSize);
	~LGraph();
	ResultCode Insert(int u, int v, T &w);
	ResultCode Remove(int u, int v);
	bool Exist(int u, int v) const;
	int Vertices() const { return n; }
	void Output();
protected:
	ENode<T> **a;
	int n, e;
	/* data */
};
template <class T>
void LGraph<T>::Output()
{
	ENode<T> *q;
	for(int i = 0; i < n; ++i) {
		q = a[i];
		while(q) {
			cout << '(' << i << ' ' << q -> adjVex << ' ' << q -> w << ')';
			q = q -> nxtArc;
		}
		cout << endl;
	}
	cout << endl << endl;
}
template <class T>
LGraph<T>::LGraph(int mSize)
{
	n = mSize;
	e = 0;
	a = new ENode<T>*[n];
	for(int i = 0; i < n; ++i)
		a[i] = NULL;
}
template <class T>
LGraph<T>::~LGraph()
{
	ENode<T> *p, *q;
	for(int i = 0; i < n; ++i) {
		p = a[i];
		q = p;
		while(p) {
			p = p -> nxtArc;
			delete q;
			q = p;
		}
	}
	delete []a;
}
template <class T>
bool LGraph<T>::Exist(int u, int v) const
{
	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return false;
	ENode<T> *p = a[u];
	while(p && p -> adjVex != v) p = p -> nxtArc;
	if(!p) return false;
	return true;
}
template <class T>
ResultCode LGraph<T>::Insert(int u, int v, T &w)
{
	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
	if(Exist(u, v)) return Duplicate;
	ENode<T> *p = new ENode<T>(v, w, a[u]);
	a[u] = p;
	e++;
	return Success;
}
template <class T>
ResultCode LGraph<T>::Remove(int u, int v)
{
	if(u < 0 || v < 0 || u > n - 1 || v > n - 1 || u == v) return Failure;
	ENode<T> *p = a[u], *q = NULL;
	while(p && p -> adjVex != v) {
		q = p;
		p = p -> nxtArc;
	}
	if(!p) return NotPresent;
	if(q) q -> nxtArc = p -> nxtArc;
	else a[u] = p -> nxtArc;
	delete p;
	e--;
	return Success;
}
template <class T>
class ExtLgraph: public LGraph<T>
{
public:
	ExtLgraph(int mSize): LGraph<T>(mSize) {}
	void TopoSort(int *order);
private:
	void CallInDegree(int *InDegree);
	/* data */
};
template <class T>
void ExtLgraph<T>::TopoSort(int *order)
{
	int *InDegree = new int[LGraph<T>::n];
	int top = -1; // 置栈顶指针为-1, 代表空栈
	ENode<T> *p;
	CallInDegree(InDegree); // 计算每个顶点的入度
	for(int i = 0; i < LGraph<T>::n; ++i)
		if(!InDegree[i]) { // 图中入度为零的顶点进栈
			InDegree[i] = top;
			top = i;
		}
	for(int i = 0; i < LGraph<T>::n; ++i) { // 生成拓扑排序
		if(top == -1) throw HasCycle; // 若堆栈为空, 说明图中存在有向环
		else {
			int j = top;
			top = InDegree[top]; // 入度为0的顶点出栈
			order[i] = j;
			cout << j << ' ';
			for(p = LGraph<T>::a[j]; p; p = p -> nxtArc) { // 检查以顶点j为尾的所有邻接点
				int k = p -> adjVex; // 将j的出邻接点入度减1
				InDegree[k]--;
				if(!InDegree[k]) { // 顶点k入度为0时进栈
					InDegree[k] = top;
					top = k;
				}
			}
		}
	}
}
template <class T>
void ExtLgraph<T>::CallInDegree(int *InDegree)
{
	for(int i = 0; i < LGraph<T>::n; ++i)
		InDegree[i] = 0; // 初始化InDegree数组
	for(int i = 0; i < LGraph<T>::n; ++i)
		for(ENode<T> *p = LGraph<T>::a[i]; p; p = p -> nxtArc) // 检查以顶点i为尾的所有邻接点
			InDegree[p -> adjVex]++; // 将顶点i的邻接点p -> adjVex的入度加1
}
int main(int argc, char const *argv[])
{
	ExtLgraph<int> lg(9);
	int w = 10; lg.Insert(0, 2, w); lg.Insert(0, 7, w);
	lg.Insert(2, 3, w); lg.Insert(3, 5, w);
	lg.Insert(3, 6, w); lg.Insert(4, 5, w);
	lg.Insert(7, 8, w); lg.Insert(8, 6, w);
	int *order = new int[9];
	lg.TopoSort(order);
	cout << endl;
	delete []order;
	return 0;
}


天龙八部TLBB系列 - 网单服务端各目录文件说明【超详细】 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等) --- 天龙八部服务端各目录详细说明 阅读详情

相关推荐

我的交叉验证翻车实录:从‘炼丹’到可靠评估,我是怎么用五折验证拯救我的图像分割模型的

本文分享了作者在医学图像分割模型评估中从失败到成功的实战经验。通过引入五折交叉验证方法,解决了传统数据划分的局限性,显著提升了模型评估的稳定性和泛化能力。文章详细介绍了Python实现、数据准备策略和训练流水线改造,为AI医疗影像分析提供了可靠的技术方案。

weixin_42625070的博客 271

TopoSort(拓扑排序)

其实说白了,拓扑排序就是一个广度优先搜索。 拓扑排序的方法如下:   (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.   (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.   (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止. 本题目是采用的邻接表存储方法。 具体的实现是用vector数组。 题目:HDU 1285http://acm....

weixin_30596343的博客 605

告别Root!用Python脚本一键解密Android微信EnMicroMsg.db数据库(附完整源码)

本文详细介绍了如何在非Root环境下使用Python脚本一键解密Android微信EnMicroMsg.db数据库。通过ADB调试接口和SQLCipher技术,实现自动化提取和解密微信聊天记录数据库,无需Root权限,适合数据分析师和普通用户安全备份数据。

weixin_29266007的博客 331

拓扑排序及算法实现

一、拓扑排序概念 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。 简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。 二、理解 在一个有向图中,对所有的节点进行排序,要求没有一个节点指向它前面的节点。...

ShyTan的博客 1万+

别再只用三次多项式了!用MATLAB手把手教你搞定七次多项式轨迹规划(附完整代码)

本文详细介绍了七次多项式在轨迹规划中的优势与应用,通过MATLAB实现从理论推导到实际代码的全过程。相比传统的三次多项式,七次多项式能精确控制位置、速度、加速度和加加速度,实现更平滑的运动控制,特别适用于工业机器人和数控机床等高精度场景。文章包含完整的MATLAB代码示例和优化技巧,帮助工程师快速掌握这一高级轨迹规划方法。

weixin_30872337的博客 298

【滚雪球学数学建模】第1节·建模入门+三步法+案例

🎓 本文收录于 《滚雪球学数学建模》专栏,本专栏专注于从零基础出发,带你循序渐进掌握数学建模的核心方法与思维路径。通过“滚雪球式”学习法,从最简单的生活化案例到经典建模工具,再到省赛、国赛真题实战演练,逐步积累知识与技能,帮助你搭建完整的建模体系。无论你是刚接触建模的新生,还是希望提升科研与竞赛能力的学者与工程师,本专栏都将为你提供一条清晰、高效、可实操的建模成长路线,助力你快速进阶,突破难点,迈向数学建模竞赛与实际应用的更高峰 🚀!

**My Coding Family** 6413

C++实现图 - 05 拓扑排序

数据结构与算法专栏 —— C++实现听名字应该很好理解,就是图中存在有向环,我们先看一个有向无环图。 我们只需要改动上图一条边,它就成为了一个有环图。拓扑排序就是对一个有向无环图构造拓扑序列的过程,听起来可能不知道从何下手,其实算法步骤很简单:重复上述两步,直至全部顶点均已输出,或者当前图不存在无前驱的顶点为止,后一种情况说明有向图中存在环。下面我们将用有向无环图和有向有环图进行举例。下图是一张有向无环图,现在我们开始进行算法步骤: 第一步:找到图中没有前驱的结点,目前图中只有一个结点 1 没有前驱。第二步

Newin2020的博客 1671

BMD101传感器协议解析与STM32实现(LCD显示波形)

1 前言 BMD101传感器是神念科技开发的心电传感器。目前有一些商家开发了BMD101传感器模块,基本上都是利用蓝牙直接传输数据到PC或手机端。而本文介绍通过串口将数据传送给单片机,并在单片机上完成数据解析和心电波形LCD显示的功能。 2 通信协议解读 BMD101 通过 UART 接口通信。这是一个标准的 UART 接口,定义为 1 个起始位,8 个数据位,1 停止位格式,波特率 57600。 串口输出的数据包格式如下: 包括Header(帧头)、data payload(数据有效载荷)、CRC校验

weixin_44509533的博客 9289

拓扑排序详解(包含算法原理图解、算法实现过程详解、算法例题变式全面讲解等)

非常详细的讲解。点开有惊喜!

aliyonghang的博客 2万+

Qt图形几何之QRect详解:从基础操作到高级功能全解析

本文全面介绍了Qt框架中的QRect类,详细解析了其核心功能和使用方法。主要内容包括:1)QRect的基本概念与多种构造函数;2)矩形属性获取和状态判断方法;3)几何操作函数(移动、调整大小等);4)几何关系判断(包含、相交等);5)坐标变换和边距处理;6)实用功能与QRectF转换;7)综合应用示例(图形界面、碰撞检测、布局管理);8)性能优化建议和常见陷阱。通过丰富的代码示例,展示了QRect在Qt图形编程中的实际应用,帮助开发者掌握矩形处理的各项操作技巧,提升图形界面开发效率。

专注现代C++实战,从核心语法到高性能编程,助力开发者深入掌握系统级编程精髓。 119

第4章-07-将WebDriver获取的Cookie传递给Requests

在使用Selenium WebDriver获取了浏览器的Cookies之后,你可以将这些Cookies传递给requests库,以便在后续的HTTP请求中使用这些Cookies。这样做可以让你模拟浏览器会话,使得请求看起来像是从之前使用Selenium WebDriver控制的浏览器发出的。

黑夜开发者的博客 692

拓扑排序(Toposort)

维基百科:拓扑排序(点我) 哈密顿回路(点我)    一.定义: 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 ∈E(G),则u在线性序列中出现在v之前。 通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。 拓扑排序就是把

LzyRapX 6442

软考中级网络工程师通关指南:从学习到实战

本文是软考中级网络工程师备考实用指南,先介绍备考前准备,包括考试时间、形式、分值等基本信息,及引导读者评估自身基础以制定学习计划;再推荐官方教材、辅导书籍、在线课程平台和学习社区等优质资源。随后梳理网络协议、设备配置、安全、规划设计等重点知识,剖析企业网络故障排查与园区网络设计典型案例。还分享真题使用、解题技巧、错题本建立等习题解答方法,给出分阶段备考、时间安排与总结反思的备考计划,最后提供考场答题顺序、检查及心态调整策略,助力考生高效备考、顺利通关。

邓邓子的博客 1855

hdu 5638 Toposort (拓扑排序+线段树)

Toposort Time Limit: 10000/5000 MS (Java/Others)Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 499Accepted Submission(s): 203 Problem Description There is a directed acycli...

weixin_30663391的博客 157

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

[poj2585]Window Pains_拓扑排序

Window Pains poj-2585     题目大意:给出一个4*4的方格表,由9种数字组成。其中,每一种数字只会出现在特定的位置,后出现的数字会覆盖之前在当前方格表内出现的。询问当前给出的方格表是否合法。     注释:输入格式需要注意。       想法:toposort裸题,我们先预处理出每一个格子可能出现的数字,如果当前数字根本不可能出现在当前格子里,那么就一定是不...

dianan0938的博客 154

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

hdu 4857逃生(反向拓扑+优先队列+逆向输出)

topoSort 1->4->2 5->3->2 结果:1)字典序从小到大排序:1 4 5 3 2 +(正向建图+正向输出+优先级小) 2)尽量要最小的靠前: 1 5 3 4 2 +(反向建图+反向输出+优先级大) #include <iostream> #include <cstdio> #include <cmath&g...

Aimer的博客 192

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

uva 10305拓扑排序

题意:给定n个二元组(u,v)表示u&lt;v。将这些元素排序。 分析:dfs搜索,如果存在有向环,那么无解。 #include&lt;cstdio&gt; #include&lt;cstring&gt; const int maxn = 1000; int n, m, G[maxn][maxn], c[maxn], topo[maxn], t; bool dfs(int u){ c[u...

timeruler的博客 176

[poj2367]Genealogical tree_拓扑排序

Genealogical tree poj-2367     题目大意:给你一个n个点关系网,求任意一个满足这个关系网的序列,使得前者是后者的上级。     注释:1<=n<=100.       想法:刚刚学习toposort,什么是toposort?         就是每一个点的遍历或选取有先决条件,那么我们可以通过队列或者栈将控制当前点的点先遍历,这样弹栈或出...

dianan0938的博客 191

拓扑排序 HDU - 1285 【Topological sort】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 思路:Toposort,每次找度==0。题目要求编号小的在前并用小顶堆 #include <iostream> #include <string> #include <algorithm> #include <queue> #include &l...

Haipai1998的博客 212

设计一个算法,用深度优先遍历法对AOV网进行拓扑排序,检测其中是否存在环。

#include<cstdio> #include<algorithm> #include<queue> using namespace std; const int maxn = 1010; int vNum; vector<int> G[maxn]; int inDegree[maxn] = {0};//记录每个点的入度 int inqNum = 0; bool topoSort(){ queue<int> Q; for(

qq_52391450的博客 336

Toop排序

#include <iostream> using namespace std; const int N = 100010; int n,m; int Value[N];//存储节点 int Next[N];//记录下一个节点的下标 int Head[N];//记录头结点 int Index;//存储位置 int Degree[N];//记录每个节点的入度 int Queue[N];//手工模拟的队列 void Add(int Start, int End) { Value[

ZZHinclude的博客 319

P1226神经网络

  提交了7次,看了无数题解,要死啊~~~。(无限吐槽这道题。。。)   据说是Toposort,我其实也不是很清楚,反正BFS就可以过;写题之前先把题看懂;   根据公式,因为入度为零的点不会被传递,所以阈值是无用的,所以那个阈值除入度为零的点以外可以直接减去(读题最重要!!!),而搜索就是从入度为零(即没有边指向的这个点)开始的,所以输入时就记录一下入读和出度;传递就规规矩矩的模拟就行了,...

weixin_30929011的博客 68

POI20143832: [Poi2014]Rally

题意给你一个有向无环图让你最小化去掉一个点之后图中的最长链。 一道toposort神题 以下要点: 1、遇到这种不知何时开始何时终止的可以加一个源一个汇 2、这题还利用了割的思想。很多这样删东西的题目都是可以用类似的思想做。 题解: 建图:建立源0汇n+1,源向所有点连边,所有点向汇连边。 首先正反toposort一遍,求出超级源点到每个点的最长链F[i],以

Fire Dancer 644

topsort top排序(队列,优先队列)。

topsort 是对有向图的排序; #include<queue>//这个是判断环的 要求拓扑序的话就在其中加上计数的部分。 using namespace std; priority_queue<int> Q; bool topsort() {   for(int i=1;i<=n;i++)   {     if(in...

weixin_30682127的博客 238

[题解]洛谷P4017 最大食物链计数

一开始不知道toposort可以做,写了个记忆化搜索,结果T了qwq 然后一看题解,豁然开朗,本蒟蒻见识浅短,还不曾知道还有这种操作 设f[i]是以i结尾的最长链个数,那么f[i]=∑f[k](k有一条出边指向i) 然后统计出度为0的点i的f[i],累加就是ans 这一过程显然可以在toposort里VAN成 代码: #include<cstdio> #inc...

weixin_30603633的博客 172
上一篇: 数据结构实验3(飞机最少环城次数问题)
下一篇: 数据结构实验4(排序算法的实现及性能分析)
GKHack
博客等级 码龄11年 48粉丝 291原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值