IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 图论之拓扑排序 -> 正文阅读

[数据结构与算法]图论之拓扑排序

前言

图论之遍历其实在之前在学习搜索的时候就已经有所学习,众所周知,要遍历一个图我们最常用的两种方法就是dfs(深度优先)和bfs(广度优先),故拓扑排序也遵循这个说法

个人定义

拓扑排序是一种按照特定方式对图的一种遍历,根据音译 top排序的想象我们容易想到用队列的顶端处理。
把AOV网(用定点表示活动,用弧表示活动间优先关系的有向图)络中各个顶点按照它们互相之间的优先关系排列成一个线性序列的过程叫做拓扑排序。

拓扑排序的适用场景

拿我们大学的课程学习进行举例,我们学了c语言学java,学了java学java高级,学了java高级和数据库学java web…如果把这些课程视作图的一个个顶点,同时告诉你某两门课程的关系,要我们整理出其顺序,该如何处理?
其实这就是我们的拓扑排序所要做的事情。

我们先跳出代码讲原理

first对图的存储:图的存储方法有很多 我们呢先采用最朴素 最有效的邻接矩阵,主要是在已知顶点的时候更方便处理。
second 寻找没有前置的顶点,即没有头的点,将其作为一个第一点,将其放入队列
third 遍历队列,每次取出队列中的一个元素,断开每个点附带的边然后这个点进入答案数组,同时判断断开边后有没有产生新的没有前置的点,若有将其放入队列。
forth 判断是否产生环:查看答案数组的长度与要排序的总点数是否相等,如果不相等说明产生了环,环在拓扑排序中是不允许存在的。
finally 下面没有了

偷了个图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最终得拓扑序列:C1–C2–C3–C4–C5–C7–C9–C10–C11–C6–C12–C8。

注意:拓扑序列并不唯一,C9–C10–C11–C6–C1–C12–C4–C2–C3–C5–C7–C8 也是一种拓扑序列。

再偷个板子

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <string>
#include <functional>
#include <cstring>
#include <cctype>
#include <stack>
#include <queue>
#include <set>
#define IOS() std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
#define Max 505
using namespace std;
vector<int> vec[Max]; //vec 存图
priority_queue<int,vector<int>,greater<int> > q; //优先队列
int in_deg[Max];//入度
int ans[Max];
int n,m;
void init() {
	for(int i=0; i<=n; i++) {
		vec[i].clear();
	}
	memset(in_deg,0,sizeof(in_deg));
	while(!q.empty()) q.pop();
}
bool topsort() {
	for(int i=0; i<n; i++) {
		if(in_deg[i]==0) {
			q.push(i);
		}
	}
	int cnt=0;
	while(!q.empty()) {
		int a=q.top();
		q.pop();
		ans[cnt++]=a;
		for(int i=0; i<vec[a].size(); i++) {
			in_deg[vec[a][i]]--;
			if(in_deg[vec[a][i]]==0) {
				q.push(vec[a][i]);
			}
		}
	}
	return cnt==n;
//	if(cnt!=n) cout<<-1<<endl;
//	else {
//		for(int i=0; i<cnt-1; i++) {
//			cout<<ans[i]<<" ";
//		}
//		cout<<ans[cnt-1]<<endl;
		cout<<endl;
//	}
}
int main() {
	IOS();
	while(cin>>n>>m) {
		if(m==0&&n==0)break;
		init();
		for(int i=0; i<m; i++) {
			int u,v;
			cin>>u>>v;
			vec[u].push_back(v);
			in_deg[v]++;
		}
		if(topsort()) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}

	return 0;
}

## 最后的最后
有些时候我们需要反向构造图,这些情况往往是对不唯一的排序结果唯一化的时候所需要做的

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:50:25  更:2021-09-24 10:53:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 12:12:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码