拓扑排序 很简单

原文链接:图论第四讲:拓扑排序

说明:CSDN和公众号文章同步发布,需要第一时间收到最新内容,请关注公众号【比特正传】。

之前的图论合集文章中讲了图的存储遍历、最短路等算法,文章链接如下

图论第一讲:图的存储及遍历

图论第二讲:Dijkstra求最短路

图论第三讲:Bellman-ford与SPFA求最短路

今天来梳理一篇关于拓扑排序的文章。

0、其他相关概念

入度:在有向图中,指向自己的箭头的个数。

1、拓扑排序基本概念

      简单点说,在有向图中,任意一对相连节点u指向v,那么排序后u一定会在v的前面,得到这样的序列的算法称为拓扑排序。

上面的说法很简陋,但是也很容易理解,如果你去查百度百科,我相信对于大部分初学者来说,看完可能就退出这篇文章了。

2、问题描述

比如一道拓扑排序的模板题,先看题

理解了这道题的意思,就很容易理解拓扑排序是什么意思了。

题目链接:

https://www.luogu.com.cn/problem/B3644

3、算法描述

拓扑排序应该算是图论中比较简单的一个算法,首先我们先思考一下,在有向图中,如果当前一个节点的入度为0,则可以认为该节点是当前图中“辈分”最大的节点。那么对当前图拓扑排序的时候,一定会先输出该节点。

有了以上共识,我们可以借助入度来实现拓扑排序。

Step1:找出当前图论中未被标记的所有入度为0的节点,加入普通队列中,这些节点的顺序就已经排好了,可以当前输出,因此需要更新他们相邻节点的入度。

Step2:针对Step1中找出的节点,依次访问这些节点的相邻结点,并将其相邻结点的入度-1(相当于删除了当前入度为0的点,所以相邻结点的入度会-1),然后判断相邻结点的入度,如果-1后等于0,那么将其加入队列。

循环上面的步骤,直到队列为空即可。

4、code

看完算法描述,结合代码浏览更容易理解


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5+7;
int n, m, u, v, in[N];
queue<int> q;
vector<int> g[N];void topsort() {for(int i=1; i<=n; i++) {if(in[i] == 0) q.push(i);  // 初始的时候,找到所有入度为0的节点,加入队列 }while(!q.empty()) {int head = q.front(); q.pop(); // 取队首并弹出,一般都是同步操作 cout << head << " ";  // 输出序列中当前的节点 for(int x : g[head]) {  // 找与其相邻的其他结点 in[x]--;  // 入度-1 if(in[x] == 0) q.push(x);  // 如果相邻结点的入度为0,那么加入队列 }}return;
}int main(){scanf("%d", &n);for(u=1; u<=n; ++u) {while(true) {scanf("%d", &v);if(v == 0) break;  // 根据题目意思,遇到0停止 g[u].push_back(v);in[v]++;  // 统计入度 }}topsort();return 0;
}

这道模板题呀,很简单,由于题目没有说,因此不需要考虑一些异常情况,比如图的连通性,如果在拓扑排序中有冲突怎么办等等,因此我们只需要考虑它的正常情况就行了,非常适合新手练习拓扑排序,自己动手完成吧。

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

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

相关文章

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑碳捕集机组与氢储能系统协调运行的源荷储低碳经济调度》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Redis监控命令和指标介绍

Redis监控的重要性 Redis监控的重要性体现在以下几个核心方面&#xff1a; 性能瓶颈发现与优化&#xff1a; 监控Redis的响应时间、QPS&#xff08;每秒查询率&#xff09;、吞吐量等性能指标&#xff0c;可以及时识别出系统在处理请求时是否存在性能瓶颈&#xff0c;比如某…

AI新工具(20240312) Midjourney官方发布角色一致性功能;免费且开源的简历制作工具;精确克隆语调、控制声音风格

1: Midjourney角色一致性功能 使人物画像在多方面高度一致成为可能。 Midjourney的角色一致性功能的使用方法如下&#xff1a; ⭐在你的输入指令后面加上 --cref URL&#xff0c;其中URL是你选择的角色图像的链接。 ⭐你可以通过 --cw 参数来调整参照的强度&#xff0c;范围…

力扣- 704. 二分查找

二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出: 4 解释…

python如何读取文件

这里的文件是txt文件&#xff0c;office文件不支持。 假如有一个pi_digits的txt文件&#xff0c;里面的内容是“3.1415926” 如果要读取这个文件的内容&#xff0c;需要调取pathlib模块&#xff0c;并把路径告知python。同时python文件必须要和目标读取文件在一个文件夹里。 …

springboot集成Quartz定时任务组件

文章目录 前言一、Quartz 是什么&#xff1f;下面是对 Java 中 Quartz 的主要概念的简单描述&#xff1a; 二、使用步骤总结 前言 平时开发中相信大家都经常用到定时任务吧&#xff0c;最近简单的就是直接使用Scheduled注解标注到方法上用注解的方式在项目运行时无法去对任务进…

【WEEK2】Learning Objectives and Summaries【SpringMVC】【English Version】

Learning Objectives: Getting Started with SpringMVC in Three Weeks - Week 2 Learning Content: Reference video tutorials【狂神说Java】SpringMVC最新教程IDEA版通俗易懂Using annotations to complete the MVC programControllerRestFul styleResult Jumping StyleDa…

剑指offer经典题目整理(四)

一、树的子结构 1.链接 树的子结构_牛客题霸_牛客网 (nowcoder.com) 2.描述 给两颗二叉树A B&#xff0c;判断B是不是A的子结构 3.思路 将问题拆解开来&#xff0c;首先是找到a树中子结构的位置&#xff0c;然后是判断是否相同&#xff0c;也就是说&#xff0c;我们需要去…

interFoam-UEqn.H/pEqn.H

压力方程 “pEqn.H” {volScalarField rAU("rAU", 1.0/UEqn.A()); // rAU:在速度方程的的最后一个解中&#xff0c;矩阵对角项系数的倒数surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU)); //转换为表面标量场volVectorField HbyA(con…

36+程序员3站考研:国家线轻松拿捏

基本情况是&#xff1a;年龄较大&#xff0c;比36还大&#xff0c;本科是自考&#xff0c;十几年来一直从事编程相关工作。 第一年考数学太慌了&#xff0c;选择题全蒙的&#xff0c;结果填空题一道没算对&#xff0c;大题全不会&#xff0c;所以尽管总分280多但是数学没过国家…

java Lambda表达式如何支持静态方法引用

java Lambda表达式如何支持静态方法引用 在Java中&#xff0c;Lambda表达式支持静态方法引用&#xff0c;允许你直接使用静态方法作为Lambda表达式的实现。静态方法引用使用类名和方法名来引用静态方法。 下面是一个简单的示例&#xff0c;展示了如何在Lambda表达式中使用静态…

Chrome下载B站视频字幕的插件

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Netty源码剖析——bind()绑定端口的分析-上(三十)

1.服务器就是在这个bind()里启动完成的 2.Bind()代码&#xff0c;追踪到创建了一个端口对象&#xff0c;并做了一些空判断&#xff0c;核心代码 doBind public ChannelFuture bind(SocketAddress localAddress){ validate(); if(localAddressnull){ throw new NullPointerExc…

软考高级:敏捷方法概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

LED基础知识分享(一)

大家好&#xff0c;我是砖一。 今天给大家分享一下&#xff0c;LED的基础知识&#xff0c;有照明行业&#xff0c;或者对LED感兴趣的朋友&#xff0c;可以学习一下&#xff0c;希望对你有用~ 一&#xff0c;什么是LED (Light Emitting Diode)? 1&#xff0c;LED是一种发出某…

AssetBundle打包与加载

官方文档 参照视频 1.AssetBundle打包 1.1设置资源的命名和后缀 命名只支持小写 1.2创建Editor文件夹&#xff0c;在里面创建编辑器打包AssetBundle的脚本 using UnityEditor; using System.IO;public class CreateAssetBundles {[MenuItem("Assets/Build AssetBun…

【机器学习】样本、特征、标签:构建智能模型的三大基石

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

【python】(9)迭代与生成器

1. 迭代的概念与原理 迭代是一种重要的编程模式,它允许我们按顺序访问容器中的每个元素,而不必事先知道容器的大小。在 Python 中,几乎所有的容器对象都可以进行迭代,包括列表、元组、字典、集合等。迭代的实现依赖于两个核心概念:可迭代对象(Iterable)和迭代器(Itera…

【dart】常用数据类型

Number num 可以声明是整数,也可以是浮点数int 只能声明整数double 只能声明浮点数 main() {int cont 6;// cont 6.3;double core 90;print(core); // 90.0num age 18;num sum 20.9; }常用api main() {int cont 6;// cont 6.3;double core 90;print(core); // 90.0n…

C++(3/12)

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和 #include <iostream>using name…