数据结构与算法:图论——拓扑排序

基础与模板:

有两个KahnDFS两个算法

下面给出Kahn的算法模板

c 复制代码
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

vector<int> topologicalSortKahn(int num, const vector<pair<int, int>>& relations){
	vector<int> result;
	vector<int> inDegree(num+1,0);	// 记录所有节点的入度
	vector<vector<int>> adj(num+1);	// 用于记录节点的连接的节点
    
	for(const auto &rel:relations){
		int from = rel.first;
		int to	 = rel.second;
		adj[from].push_back(to);	// 写入每个节点连接的节点
		inDegree[to]++;				// 写入入度
	}
	
	queue<int> q;					// 用于记录入度为0的节点
	// 遍历节点,把入度为0的点写入q
	// 这里需要注意节点到底是从0开始还是从1开始
	for(int i = 0;i< num;++i){
		if(inDegree[i] == 0){
			q.push(i);
		}
	}
	// 提取入度为0的节点,删除其连接,不断更新入度
	while(!q.empty()){
		int current= q.front();
		q.pop();
		result.push_back(current);		
		for(int next : adj[current]){
			inDegree[next]--;		// 每个下一节点的入度减1
			if(inDegree[next]==0){	// 入度减1后判断为0加入q
				q.push(next);
			}
		}
	}
    if(result.size() != num) return{-1}; // 判断是环,返回-1
	return result;
}

int main(){
	int N,M;
	cin>>N>>M; 
	vector<pair<int,int>>  inRelation;
	int from,to;
	while(M--){
		cin>>from>>to;
		inRelation.emplace_back(pair<int,int>{from,to});
	}
	vector<int> res = topologicalSortKahn(N,inRelation);
	for(size_t i = 0;i < res.size()-1;i++){
		cout<<res[i]<<" ";
	}
	cout<<res.back();
}

图的拓扑排序题目leetcode

题号 标题 题解 标签 难度
0207 课程表 Python 深度优先搜索、广度优先搜索、图、拓扑排序 中等
0210 课程表 II Python 深度优先搜索、广度优先搜索、图、拓扑排序 中等
1136 并行课程 Python 图、拓扑排序 中等
2050 并行课程 III Python 图、拓扑排序、数组、动态规划 困难
0802 找到最终的安全状态 Python 深度优先搜索、广度优先搜索、图、拓扑排序 中等
0851 喧闹和富有 Python 深度优先搜索、图、拓扑排序、数组 中等

题目1、117. 软件构建

卡吗网代码编辑真不错

直接套模板

题目2、210. 课程表 II

c 复制代码
class Solution {
public:
	vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
		vector<int> result;
		vector<int> inDegree(numCourses+1,0);	// 记录所有节点的入度
		vector<vector<int>> adj(numCourses+1);	// 用于记录节点的连接的节点
		for(const auto &rel:prerequisites){
			int from = rel[0];
			int to	 = rel[1];
			adj[from].push_back(to);	// 写入每个节点连接的节点
			inDegree[to]++;				// 写入入度
		}
		
		queue<int> q;					// 用于记录入度为0的节点
		// 遍历节点,把入度为0的点写入q
		// 这里需要注意节点到底是从0开始还是从1开始
		for(int i = 0;i< numCourses;++i){
			if(inDegree[i] == 0){
				q.push(i);
			}
		}
		// 提取入度为0的节点,删除其连接,不断更新入度
		while(!q.empty()){
			int current= q.front();
			q.pop();
			result.push_back(current);		
			for(int next : adj[current]){
				inDegree[next]--;		// 每个下一节点的入度减1
				if(inDegree[next]==0){	// 入度减1后判断为0加入q
					q.push(next);
				}
			}
		}
		if(result.size() != static_cast<size_t>(numCourses)) return{}; // 判断是环,返回{}
		return result;
	}
};

题目3、任务调度算法



c 复制代码
#include <vector>
#include <utility>
#include <queue>
#include <algorithm>


using namespace std;

class Solution {
public:
	int GetMinT	ime(int taskNum, const vector<pair<int, int>>& relations)
	{
		vector<vector<int>> adj(taskNum+1);
		vector<int> inDegree(taskNum + 1, 0);
		vector<int> dp(taskNum + 1, 1);
		
		for (const auto& rel : relations) {
			int from = rel.second; 
			int to = rel.first;    
			adj[from].push_back(to);
			inDegree[to]++;
		}
		queue<int> q;
		for (int i = 1; i <= taskNum; ++i) {
			if (inDegree[i] == 0) {
				q.push(i);
			}
		}
		
		while (!q.empty()) {
			int current = q.front();
			q.pop();
			for (int next : adj[current]) {
				dp[next] = max(dp[next], dp[current] + 1);
				if (--inDegree[next] == 0) {
					q.push(next);
				}
			}
		}
		return *max_element(dp.begin() + 1, dp.end());

	}
};

题目4、207. 课程表 - 力扣

这里就是判断是否有环

相关推荐
程序猿编码2 小时前
二进制签名查找器(Aho-Corasick 自动机):设计思路与实现原理(C/C++代码实现)
c语言·c++·网络安全·二进制·逆向工程·ac自动机
重生之我是Java开发战士2 小时前
【C语言】文件操作全解析
c语言·开发语言
小指纹7 小时前
河南萌新联赛2025第(四)场【补题】
数据结构·c++·算法·macos·objective-c·cocoa·图论
F_D_Z7 小时前
【感知机】感知机(perceptron)模型与几何解释
学习·算法·支持向量机
橘颂TA8 小时前
【Linux】特效爆满的Vim的配置方法 and make/Makefile原理
linux·运维·服务器·vim
HW-BASE8 小时前
C语言的结构体与联合体
c语言·单片机·嵌入式·编程·c
AI大法师9 小时前
企业级Linux服务器安全:防火墙规则配置与Web/SSH服务优化指南
linux·服务器·安全
慕y2749 小时前
Java学习第一百一十部分——CI/CD
java·学习·ci/cd
Asu52029 小时前
思途AOP学习笔记 0806
java·sql·学习·mybatis
花小璇学linux9 小时前
imx6ull-驱动开发篇10——pinctrl 子系统
linux·驱动开发·imx6ull·嵌入式软件