当前位置: 首页 > news >正文

如何判断有向无环图:构造有向无环图

拓扑序列:可以用来判断一个有向图是否有环!
拓扑排序可以判断有向图是否存在环。我们可以对任意有向图执行上述过程,在完成后检查A序列的长度。 若A序列的长度小于图中点的数量,则说明某些节点未被遍历,进而说明图中存在环。

拓扑排序是结合bfs框架来实现的,每次从入度为0的点开始搜索;所以需要先预处理出来所有入度为0的节点,入队,然后去遍历这些入度为0的点,每次将这些点进行逻辑上的删除,然后更新它的直接邻接点的入度,如果直接邻接点的入度减为0,则将其也入队!

  1. 建立一个队列,负责按照拓扑序列存取节点。
  2. 预处理所有点的入度d[i], 起初把所有入度为0的点入队。
  3. 取出队头节点t, 把 t 加入拓扑序列 – 队列q的末尾。
  4. 对于从x出发的每条边x->y,y即为x的直接邻接点, 把d[y]−−。若被减为0, 则把y入队。
  5. 重复第3∼4步直到队列为空, 此时队列q即为所求。

本题中心思想: 用 已确定方向的边 建好图后,给 未确定方向的边 设置方向 这部操作其实就是 加边 行为。如果当前图中已经存在 环
了,那么加额外的边是不能去掉这个 环 的(除非删掉环上的某一条边) 大致就是以上意思

由于我们只建立了有向边,而无向边的话是没有建立的,所以意味着建立的有向图不会经过所有的顶点,,那为什么生成的拓扑序列 就能够确保经过所有的顶点呢?

因为属于不同连通块亦能构成拓扑序,拓扑排序本身不会被局限在一个连通块内

对于无向边的节点,我们需要知道它在拓扑序列中的位置,而拓扑序列我们已经预处理出来了,只需要求出拓扑序列里,含无向边的两个点,让它们按照拓扑序列从前往后指向,就必然不会破坏拓扑序列并且合法!

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;const int N = 2e5 + 10, M = N;
int T, n, m;
int top[N], pos[N];     //存放拓扑序!
int h[N], e[M], ne[M], d[N], idx;
struct Edge{int a, b;
}edge[M];void add (int a, int b)
{e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}bool topsort ()
{queue<int> q;   //定义一个队列!//预处理出来所有入度为0的节点:for (int i=1; i <= n; i ++)if (!d[i])q.push(i);int cnt = 0;while (q.size()){auto t = q.front();q.pop();top[cnt ++] = t;    //存放拓扑序列! for (int i=h[t]; ~i; i = ne[i]){int j = e[i];d[j] --;if (d[j] == 0)q.push(j);}}//判断存放的元素个数:if (cnt < n) return false;else return true;
}int main()
{cin >> T;while (T --){int cnt = 0;//初始化:memset (h, -1, sizeof (h));memset (d, 0, sizeof (d));  //度数数组!idx = 0;scanf ("%d%d", &n, &m);while (m --){int t, x, y;scanf("%d%d%d", &t, &x, &y);if (!t) edge[cnt ++] = {x, y};else{   //即为有向边!add (x, y);d[y] ++;}}if (!topsort())    //利用拓扑序列判断是否有环puts("NO");else{puts("YES");for (int i=1; i <= n; i ++) //输出拓扑序列:for (int j=h[i]; ~j; j = ne[j])printf ("%d %d\n", i, e[j]);    //指代有向边!//记录每个点的位置://pos[i]:表示的是i号节点在拓扑序列中的位置for (int i=0; i < n; i ++) pos[top[i]] = i;for (int i=0; i < cnt; i ++){int a = edge[i].a, b = edge[i].b;if (pos[a] > pos[b]) swap(a, b);printf ("%d %d\n", a, b);}}}return 0;
}```

相关文章:

如何判断有向无环图:构造有向无环图

拓扑序列&#xff1a;可以用来判断一个有向图是否有环&#xff01; 拓扑排序可以判断有向图是否存在环。我们可以对任意有向图执行上述过程&#xff0c;在完成后检查A序列的长度。 若A序列的长度小于图中点的数量&#xff0c;则说明某些节点未被遍历&#xff0c;进而说明图中存…...

【2022.1.3】手脱压缩壳练习(含练习exe)

【2022.1.3】手脱压缩壳练习&#xff08;含练习exe&#xff09; 文章目录【2022.1.3】手脱压缩壳练习&#xff08;含练习exe&#xff09;0、简介1、单步跟踪法&#xff08;#&#xff09;方法介绍&#xff08;0&#xff09;练习exe下载&#xff08;1&#xff09;、查看源程序&am…...

【异或哈希】CF855 div3 F

感觉这道题跟之前有一题特别像&#xff0c;都是异或哈希感觉这种题应该很典&#xff0c;记录一下(66条消息) Codeforces Round #841 (Div. 2) and Divide by Zero【异或差分动态map维护】 2022 C. Even Subarrays_lamentropetion的博客-CSDN博客Problem - F - Codeforces题意&a…...

深度学习|改进两阶段鲁棒优化算法i-ccg

目录 1 主要内容 2 改进算法 2.1 CC&G算法的优势 2.2 i-CCG算法简介 3 结果对比 1 主要内容 自从2013年的求解两阶段鲁棒优化模型的列和约束生成算法&#xff08;CC&G&#xff09;被提出之后&#xff0c;基本没有实质性的创新&#xff0c;都是围绕该算法在各个领…...

C++11轻松打印本地时间

C11之前&#xff0c;想要获取时间并对其打印是有些困难的&#xff0c;因为C并没有标准时间库。想要对时间进行统计就需要调用C库&#xff0c;并且我们要考虑这样的调用是否能很好的封装到我们的类中。 C11之后&#xff0c;STL提供了 chrono 库&#xff0c;其让对时间的操作更加…...

Eureka - 总览

文章目录前言架构注册中心 Eureka Server服务提供者 Eureka Client服务消费者 Eureka Client总结资源前言 微服务&#xff08;Microservices&#xff0c;一种软件架构风格&#xff09;核心的组件包括注册中心&#xff0c;随着微服务的发展&#xff0c;出现了很多注册中心的解决…...

【算法设计-枚举、分治】素数、约数、质因数分解

文章目录1. 素数判定2. 素数筛选法3. 质因数分解4. 求一个数的约数5. 求两个数的最大公约数&#xff08;GCD&#xff09;6. 求两个数的最小公倍数&#xff08;LCM&#xff09;1. 素数判定 判定从 2 到sqrt(n)依次能否把 n 整除&#xff0c;若存在可以整除的数则说明 n 不是素数…...

【第十四届蓝桥杯】第三期模拟赛B组C++题解(待修正+持续更新-ing)

文章目录写在前面一、找最小数题目描述解题报告1、大体思路2、代码详解二、求列名题目描述解题报告1、大体思路2、代码详解三、求日期数题目描述解题报告1、大体思路2、代码详解四、取数题目描述解题报告1、大体思路2、代码详解五、最大连通分块题目描述解题报告1、大体思路2、…...

线程池和ThreadLocal详解

线程池和ThreadLocal详解线程池池化模式&#xff1a;线程池里的线程数量设定为多少比较合适?添加线程规则&#xff1a;实现原理&#xff1a;线程池实现任务复用的原理线程池状态&#xff1a;Executors 创线程池工具类手动创建&#xff08;更推荐&#xff09;&#xff1a;自动创…...

[深入理解SSD系列综述 1.7] SSD固态存储市场发展分析与预测_固态存储技术发展方向(2022to2023)

前言 自2020年疫情爆发以来,远程办公、网上教育、流媒体等等应用引爆对消费电子及云服务的需求增长,全球数字化转型加速,带来了两年的闪存风光时刻。然而,进入2022年,在俄乌冲突、疫情重燃、通胀上升等一系列事件冲击下,全球经济下行风险加剧,对智能手机、PC等科技产品的…...

【2021.12.25】ctf逆向中常见加密算法和编码识别

【2021.12.25】ctf逆向中常见加密算法和编码识别&#xff08;含exe及wp&#xff09; 文章目录【2021.12.25】ctf逆向中常见加密算法和编码识别&#xff08;含exe及wp&#xff09;0、前言1、基础加密手法2、base64&#xff08;1&#xff09;原理&#xff1a;&#xff08;2&#…...

【数据结构初阶】堆排序

目录 前言 概念 堆排序的实现 1.建堆 &#xff08;1&#xff09;堆向上调整算法 &#xff08;2&#xff09;堆的向下调整算法 2. 利用堆删除思想来进行排序 3.堆排序的时间复杂度 4.源码 总结 前言 前边我们学习了堆的实现&#xff0c;对堆的每个接口都进行了详细的讲…...

Day5: platformDriver-1

Platform Driver (1) Linux kernel中大部分设备可以归结为平台设备&#xff0c;因此大部分的驱动是平台驱动&#xff08;patform driver&#xff09; 什么是平台设备 平台设备是linux的设备模型中一类设备的抽象。 内核中的描述&#xff1a; Platform devices are devices t…...

开发手册——一、编程规约_7.控制语句

这篇文章主要梳理了在java的实际开发过程中的编程规范问题。本篇文章主要借鉴于《阿里巴巴java开发手册终极版》 下面我们一起来看一下吧。 1. 【强制】在一个 switch 块内&#xff0c;每个 case 要么通过 break / return 等来终止&#xff0c;要么注释说明程序将继续执行到哪…...

python每日学9 : windows上配置gitee的远程仓库,git的初步使用

在开发中&#xff0c;如果遇到复杂的项目&#xff0c;使用版本控制是非常有必要的&#xff0c;如果涉及到多端开发&#xff0c;那么还需要使用远程仓库。本文作个简单记录&#xff0c;记录下git初步使用。 1 下载与安装 git还有几个ui版本&#xff0c;但是开始使用的话&#…...

精确率与召回率,ROC曲线与PR曲线

精确率与召回率&#xff0c;ROC曲线与PR曲线 在机器学习的算法评估中&#xff0c;尤其是分类算法评估中&#xff0c;我们经常听到精确率(precision)与召回率(recall)&#xff0c;ROC曲线与PR曲线这些概念&#xff0c;那这些概念到底有什么用处呢&#xff1f; 首先&#xff0c…...

现代操作系统——Linux架构与学习

小白的疑惑 在我决定从事嵌入式&#xff08;应用层&#xff09;方面的工作时&#xff0c;我查询了大量资料该如何学习&#xff0c;几乎所有观点不约而同的都指向了学习好Linux&#xff0c;大部分工作都是在Linux环境下来进行工作的。于是我雄心勃勃的去下载Linux&#xff0c;可…...

中文代码82

PK 嘚釦 docProps/PK 嘚釦羸 r docProps/app.xml潙蚽?勶曻Q顗濔S? 錞礖剅D柍珘m?鳞?ぷ辷f硌?2?upc厭Y樐8 rU y搪m眾&a?珪?紓 玺鶋瑣襚? ?i嘲rN?布倖儇?攊橌??嚗猝)芻矂2吟腊K湞?CK臶>鸘\?ΔF滋齢q旮T?桀?;偉 A軥v蕯朾偤佷3?е…...

顺序表(一篇带你掌握顺序表)

目录 一、顺序表是什么 1.1 概念 1.2 分类 1.3 结构 二、顺序表的基本操作 2.1 前绪准备 2.2 初始化 2.3 扩容 2.5 尾插 2.6 打印 2.7 尾删 2.8 头插 2.9 头删 2.10 在pos位置插入 2.11 删除pos位置的数据 2.12 查找 三、完整代码 3.1 Test.c文件 3.2 SeqList.h…...

【SpringCloud】SpringCloud教程之Feign实战

目录前言SpringCloud Feign远程服务调用一.需求二.两个服务的yml配置和访问路径三.使用RestTemplate远程调用(order服务内编写)四.构建Feign(order服务内配置)五.自定义Feign配置(order服务内配置)六.Feign配置日志(oder服务内配置)七.Feign调优(order服务内配置)八.抽离Feign前…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...