拓扑排序(广度优先搜索实现)

2023-10-26

有向无环图可以用来表示各种事物的顺序,比如工作顺序。一些事情必须在另一些事情完成之后才能开始进行。那么,为了获得正确的工作顺序(一件事情开始之前,必须保证它的前置条件全部满足),就需要用到拓扑排序。

拓扑排序其实就是在有向无环图中,只要存在边(u,v),那就让u排在v前面。

我们可以通过广度优先搜索或者深度优先搜索来实现拓扑排序。

广度优先的思路就是对每个入度为0的且未被访问过的节点进行广度优先搜索。

在搜索过程中,只要搜索了u与v之间的边,那就将v的入度减1,相当于删除边的操作。入度为零就代表着它的前置条件已经完全满足。一个节点只有当其入度为0且未被访问过,才对其进行广度优先搜索。

下面是通过bfs拓扑排序的伪代码

 

利用DFS进行拓扑排序的思路相对简单,就是循环以当前仍未搜索的节点为起点,进行dfs,然后逆序把节点id存入列表中。但是,对于大规模的图来说,深度优先搜索很容易栈溢出,并且由于递归调用有开销,所以,采用BFS会更好。

对于题目 GRL_4_B ,采用BFS的AC代码如下

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define MAXV 10005


vector<int> vec[MAXV];
vector<int> ans;

int v, e;

int indeg[MAXV] = {0};
bool vis[MAXV] = {false};

void bfs(int u)
{
    queue<int>q;
    vis[u] = true;
    q.push(u);

    while(!q.empty())
    {
        int t = q.front();
        q.pop();
        ans.push_back(t);
        for(int x:vec[t])
        {
            indeg[x]--;
            if(indeg[x]==0&&vis[x]==false)
            {
                q.push(x);
                vis[x] = true;

            }
        }
    }
}

void solve()
{
    for (int i = 0; i < v; ++i)
    {
        if (indeg[i] == 0 && vis[i] == false)
        {
            bfs(i);
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> v >> e;

    int s, t;
    for (int i = 0; i < e; ++i)
    {
        cin >> s >> t;
        vec[s].push_back(t);
        indeg[t]++;
    }
    solve();
    for(int x:ans)
    {
        cout<<x<<endl;
    }
}

 

转载请注明来源:https://www.longjin666.top/?p=762

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

拓扑排序(广度优先搜索实现) 的相关文章

  • .NET C# - MigraDoc - 如何更改文档字符集?

    我已经寻找过这个问题的解决方案 但仍然找不到答案 任何帮助 将不胜感激 Document document new Document Section section document AddSection Paragraph paragra
  • c++03 初始化具有多个参数的对象数组

    这可能是一个简单的问题 但我正在尝试使用参数化构造函数初始化对象数组 例如 class A public int b c d A int i int j void A A int i int j d rand b 2 i c 3 j voi
  • 以编程方式最大化屏幕一半的窗口

    我想最大化屏幕左侧的随机窗口 我可以在我的代码中使用 Windows Aero 函数吗 这个窗口can像用鼠标一样最大化 我只想以编程方式做到这一点 I use C 我可以得到IntPtr窗户的 如果可能的话 不要伪造鼠标或键盘输入 这可以
  • 如何在命名管道 (mkfifo) 上执行非阻塞 fopen?

    如果我有一个程序使用 mkfifo 创建并尝试打开命名管道 如何在不阻塞的情况下打开管道进行读取或写入 具体来说 我正在编写一个 C 程序 它可以在有或没有 GUI 的情况下运行 用 Java 编写 在 C 程序中 我使用 mkfifo 成
  • 如何在 CUDA 中执行多个矩阵乘法?

    我有一个方阵数组int M 10 以便M i 定位第一个元素i th 矩阵 我想将所有矩阵相乘M i 通过另一个矩阵N 这样我就收到了方阵数组int P 10 作为输出 我看到有不同的可能性 分配不同元素的计算M i 到不同的线程 例如 我
  • XML 字符串到 XML 文档

    我有一个完整的 XML 文档String我需要将其转换为 XML 文档并解析文档中的标签 此代码示例取自csharp examples net http www csharp examples net xml nodes by name 写
  • 如何使用 C# 获取打印作业状态

    我可以打印文档 但不知道如何获取其状态 我查阅了很多资源 MSDN http support microsoft com kb 322091 检查工作状态的链接 https stackoverflow com questions 55637
  • 这个具有多个值(变量)的 return 语句如何工作? [复制]

    这个问题在这里已经有答案了 我试图了解 C 函数中按值传递和返回是如何发生的 我发现一段代码如下 include
  • 用于更改可为空和非空数据类型的数据注释是什么?

    我认为这对于有经验的程序员来说应该很简单 但事实就是如此 我正在开发一个首先使用实体 框架代码的项目 我还启用了迁移并设置为自动 可爱的功能 我愚蠢地在我的实体类中声明了一种错误的数据类型 现在我意识到它不适用于我想要做的事情 一定是自动完
  • 为什么无法在 android 中包含 iostream?

    已安装 android ndk r7 并尝试编译 cpp 文件 include
  • const QList 警告 = QList() << 0; gcc 4.7.2 的段错误

    因此 主题行中提到的代码会导致 Qt 4 8 3 和 gcc 4 7 2 出现分段错误 这是在 cpp 文件中的任何类 结构之外 并且与 gcc 4 4 一起使用 const QList
  • 在下载的同时从 UnityWebRequest 获取数据?

    我有这段代码可以进行 REST 调用 public IEnumerator GetCooroutine string route string finalURL URL route UnityWebRequest www UnityWebR
  • 如何从函数调用事件处理程序?

    我有一个类 我从中调用一个函数ABC string st 带字符串参数 该函数定义在一个Form class Form1 我有一个列表视图 想要从函数中自动调用列表视图 mouse click 事件 我该如何做到这一点 您不能调用另一个类的
  • 哪个对缓存最友好?

    我试图很好地掌握面向数据的设计以及如何在考虑缓存的情况下进行最佳编程 基本上有两种情况我无法完全确定哪个更好以及为什么 是拥有一个对象向量更好 还是拥有对象原子数据的多个向量更好 A 对象向量示例 struct A GLsizei mInd
  • 静态、非成员或静态非成员函数?

    每当我有一些 实用 方向的功能时 我最终都会想知道哪个选项是最好的 例如 在我正在工作的上下文中打印消息结构 自己的或外部的 一些编码 解码代码或一些有用的转换函数 我想到的选项是 1 辅助类 结构中的静态函数 struct helper
  • NullValueHandling.Ignore 使用 JsonConverter::WriteJson

    我正在尝试执行自定义序列化 所有快乐路径代码都可以工作 但空值路径的行为并不像我想要的那样 我已将序列化器设置设置为NullValueHandling Ignore我的对象图的其他部分为空 并且不使用我的自定义序列化 已删除空值 看起来 N
  • 编译器如何解析在变长数组之后声明的变量的地址?

    假设我有以下函数 它使用可变长度数组 void func int size int var1 int arr size int var2 编译器如何确定地址var2 我能想到的唯一方法就是放置arr after var1 and var2
  • 以编程方式更改 Windows 服务用户

    我需要以编程方式更改 Windows 服务的登录用户 我使用以下代码来做到这一点 string objPath string Format Win32 Service Name 0 ServiceName using ManagementO
  • 使用 winforms 、 mdi 、父子窗体,在父窗体下指定空间打开子窗体

    我有一个 winform MAINFORM 需要以此形式打开子窗体 如图所示 黑色部分是一个面板并且包含一个编号 具有多个节点的 LinkLabels 和 Treeview 在其余部分中 我想在单击面板上的链接标签时显示子表单 子表单应完全
  • REQ/REP 模式中的 ZeroMQ FiniteStateMachineException

    我有两个简单的组件 它们应该使用 REQ REP ZeroMQ 模式相互通信 服务器 REP Socket 是使用 pyzmq 在 Python 中实现的 import zmq def launch server print Launchi

随机推荐

  • 关于STM32的SPI使用DAM首发的回调问题

    本人第一次使用HAL库 然后用SPI操作FLAH 担心数据量大 于是打算使用DMA 之前是用的LL库 然后发现了一个问题 SPI怎么都接收不到数据 想了一下应该是片选引脚的问题 我应该在DMA传输结束时关闭引脚 但是之前都是用LL库 判断标
  • spring无侵入自动生成接口文档

    背景 spring cloud多个微服务开发了很多接口 紧急对接前端 需要快速提供一批接口的文档 且不同微服务的接口由多位同事开发且注释非常的少各有不同 现在需要不修改代码不添加注释的情况下能自动的扫描接口并生成文档 本文将详细介绍实现此需
  • X264的参考帧设置

    1 以r1884为例 r ref lt 整数 gt Reference Frame 即参考帧 决定最多可能的参考帧数 有效范围值1 16 该值越大 压缩率越高 但大于6后对压缩率的贡献很低 可以看压制完后x264 info ref 项 例如
  • sqlserver 登录名和用户名

    解释 登录名 通俗的讲 平时连接数据库是用的就是登录名 而不是用户名 是数据库服务级别 登录数据库之后 这个登录名有什么权限 比如可以访问那个数据库 或者表 存储过程 视图等 甚至字段权限 是有与之对应的用户 用户名 决定 注 也可以从服务
  • 手风琴(折叠面板)

    目录 一 Layui手风琴 1 1 引用layui的css和js 1 2 开启手风琴的代码示例 1 3 静态数据 1 4 最终效果图 二 Bootstrap手风琴 2 1 引用Bootstrap的css和js 2 2 开启手风琴的代码示例
  • Python 第一章 基础知识(6) 函数

    函数就像可以用来实现特定功能的小程序一样 Python的很多函数都能做很奇妙的事情 先来介绍一个内建函数 即是Python自带的已经定义好的函数 可以直接用 gt gt gt pow 2 3 8 这个函数实现了2 2 2的算法 这种使用函数
  • Angular 中 web worker的使用

    web worker就是在web应用程序中使用的worker 这个worker是独立于web主线程的 在后台运行的线程 web worker的优点就是可以将工作交给独立的其他线程去做 这样就不会阻塞主线程 第一步 ng g webWorke
  • 快速生成26个英文字母

    在学习中经常会拿26个英文字母序列做为字符串的例子来说明 但是自己又不想每次都自己手动输入 所以就想写个方法能快速的生成这个字符串 generate 26 english Characters return void public stat
  • C# 9.0:Records

    转自 翁智华 cnblogs com wzh2010 p 13950647 html 概述 在C 9 0下record是一个关键字 微软官方目前暂时将它翻译为记录类型 传统面向对象的编程的核心思想是一个对象有着唯一标识 封装着随时可变的状态
  • JenKins结合cppcheck及cpplint进行代码风格及静态代码检测

    JenKins结合cppcheck及cpplint 最近公司需要在Jenkins上安装cppcheck及cpplint进行代码风格及静态代码检测 这里记录下过程 前提条件 安装了Jenkins 步骤如下 第一步 安装cppcheck并配置环
  • [Linux] yum和apt-get用法及区别

    一般来说著名的linux系统基本上分两大类 1 RedHat系列 Redhat Centos Fedora等 2 Debian系列 Debian Ubuntu等 RedHat 系列 1 常见的安装包格式 rpm包 安装rpm包的命令是 rp
  • vs2019调试时中文乱码解决办法

    vs2013 vs2019系列文章目录 文章目录 vs2013 vs2019系列文章目录 问题描述 一 解决 解决方法1 在我机器上仍然未解决 解决方法2 在我机器上可行 调试时中文显示效果 问题描述 vs2019调试时中文乱码 但是在vs
  • except Exception as e作用

    小记 今天在查看poc时 发现这段代码不理解 所以B站搜索了一下 把别人讲的内容爬了一下 coding utf 8 a int input 请输入数字0 try if a 0 print a except Exception as e 作用
  • Redis高可用集群(哨兵、集群)

    文章目录 前言 一 主从复制 1 1 主从复制的作用 1 2 主从复制流程 1 3 主从复制搭建 二 哨兵模式 2 1 哨兵模式的作用 2 2 哨兵结构的组成 2 3 故障转移机制 2 4 哨兵模式搭建 三 集群模式 3 1 集群的作用 3
  • shell 脚本调试工具

    bashdb 是一个类似GDB的脚本调试软件 具有断点 单步执行 观察变量等功能 安装方法 sudo apt get install bashdb bashdb 使用方法 bashdb options script name script
  • vue element-ui el-table表格二次封装 自定义el-table表格组件 vue封装表格组件

    CommTable vue table组件
  • 多人连线的枪战游戏

    Simple Blueprint Multiplayer 是一个完全由 蓝图 和 UMG 界面 编写的游戏 可以作为如何使用蓝图的 Session Nodes 打造游戏中的多人部分的使用示例 这里有一个主菜单 一个服务器列表 以及一个简单的
  • java如何将null转化为空串也就是empty

    java如何将null转化为空串也就是empty 前言 在说转换之前 简单说一下它们之间的区别 如下 1 null不指向任何对象 相当于没有任何值 而 代表一个长度为0的字符串 2 null不分配内存空间 而 会分配内存空间 那如何将nul
  • HTTP 2.0 与HTTP1.1的差别

    前面的话 在说HTTP2 0前 先说一说发展到HTTP1 1做了哪些升级 推荐好文 一文读懂HTTP 2及HTTP 3特性 HTTP1 1的升级 目前使用最广泛的HTTP1 1做了哪些重大升级 默认长连接 HTTP1 0也提供长连接 但是默
  • 拓扑排序(广度优先搜索实现)

    有向无环图可以用来表示各种事物的顺序 比如工作顺序 一些事情必须在另一些事情完成之后才能开始进行 那么 为了获得正确的工作顺序 一件事情开始之前 必须保证它的前置条件全部满足 就需要用到拓扑排序 拓扑排序其实就是在有向无环图中 只要存在边