图论03-【无权无向】-图的深度优先遍历-路径问题/检测环/二分图

文章目录

  • 1. 代码仓库
  • 2. 单源路径
    • 2.1 思路
    • 2.2 主要代码
  • 3. 所有点对路径
    • 3.1 思路
    • 3.2 主要代码
  • 4. 路径问题的优化-提前结束递归
    • 4.1 思路
    • 4.2 主要代码
  • 5. 检测环
    • 5.1 思路
    • 5.2 主要代码
  • 6. 二分图
    • 6.1 思路
    • 6.2 主要代码
      • 6.2.1 遍历每个联通分量
      • 6.2.2 递归判断相邻两点的颜色是否一致

1. 代码仓库

https://github.com/Chufeng-Jiang/Graph-Theory

2. 单源路径

2.1 思路

  1. 构造visited数组和pre数组
    1.1 visited数组记录当前节点是否访问过
    也可以不使用visited数组,pre数组全部初始化为-1,联通的顶点对应的pre数组的值为前一个节点,pre数组中值为-1的都是不连通的顶点。
    1.2 pre数组记录当前节点的前一个节点
  2. 使用pre数组对终点进行反推回源点,并记录
  3. 将终点到原点的路径,反序输出

2.2 主要代码

   public SingleSourcePath(Graph G, int s){ //单源路径,要把源s传进来,而且只考虑与s连通的顶点,不连通的不考虑G.validateVertex(s);this.G = G;this.s = s;visited = new boolean[G.V()];pre = new int[G.V()];dfs(s, s);}private void dfs(int v, int parent){ //参数一:当前顶点; 参数二:上一个顶点visited[v] = true;pre[v] = parent;for(int w: G.adj(v)) //跟v相邻的所有顶点,相当于v是源,遍历与当前顶点相邻的所有点if(!visited[w])dfs(w, v); //(顶点,源)}public Iterable<Integer> path(int t){ //从源到t的路径ArrayList<Integer> res = new ArrayList<Integer>();if(!isConnectedTo(t)) return res;	int cur = t; // 从t往回找while(cur != s){res.add(cur); //添加当前节点(循环内不包含源)cur = pre[cur]; //pre[cur]的值是cur的上一个节点}res.add(s); //添加源Collections.reverse(res);return res;}

3. 所有点对路径

3.1 思路

对所有顶点进行遍历,创建每一个点的单源路径数组。

3.2 主要代码

public AllPairsPath(Graph G){this.G = G;paths = new SingleSourcePath[G.V()];for(int v = 0; v < G.V(); v ++)paths[v] = new SingleSourcePath(G, v);
}

4. 路径问题的优化-提前结束递归

4.1 思路

在填充visited和pre数组的时候,如果遇到了目标节点,直接结束。剩下的节点不进行处理。

if(v == t) return true; //程序出口,当到达t顶点时,返回true提前结束递归,而不仅仅是返回return

4.2 主要代码

    private boolean dfs(int v, int parent){visited[v] = true;pre[v] = parent;if(v == t) return true; //程序出口,当到达t顶点时,返回true提前结束递归,而不仅仅是返回returnfor(int w: G.adj(v)) //遍历与v相邻的顶点if(!visited[w]) //如果相邻的顶点没有被访问过if(dfs(w, v)) //递归遍历相邻的顶点,如果到达 v==t,则值为truereturn true; //提前返回truereturn false; // 转一圈没法达到t,就可以返回false}

5. 检测环

5.1 思路

从某一点v出发,找到了点w,w被访问过,并且w不是v的前一个节点

5.2 主要代码

public CycleDetection(Graph G){this.G = G;visited = new boolean[G.V()];//要对所有的连通分量进行环检测for(int v = 0; v < G.V(); v ++)if(!visited[v])  //如果没有访问过if(dfs(v, v)){ //则进行深度搜索,如果深度搜索出来的是true,说明有环,则进入循环breakhasCycle = true;break;}
}private boolean dfs(int v, int parent){visited[v] = true;for(int w: G.adj(v))if(!visited[w]){ //case1:如果w没有被访问过if(dfs(w, v)) //如果dfs返回true,则说明有环。因为dfs有环才会返回true,那么进入if选择语句return true提前结束return true;}else if(w != parent) // case2:从v出发,找到了w,w还被访问过,并且w不是v的前一个节点return true; // 此时找到了环//其他的情况,找一圈没有找到环,返回falsereturn false;
}

6. 二分图

在这里插入图片描述

6.1 思路

二分图可以通过染色过程把顶点区分开,
[-1:顶点还没染色]
[0:一种颜色]
[1:另外一种颜色]

6.2 主要代码

6.2.1 遍历每个联通分量

  1. dfs(v, 0) 返回true代表相连的两点颜色不一样,暂未出现矛盾;
  2. dfs(v, 0) 返回false代表相连的两点颜色一样,不符合二分图的定义,因此进入if语句块,设置isBipartite = false;并且提前结束循环。
for(int v = 0; v < G.V(); v ++)if(!visited[v]) //如果没有被访问// 起始的时候把v统一染成0色,如果dfs返回的false,进入下面结构体,否则跳出执行v++if(!dfs(v, 0)){ isBipartite = false; // 检测出错了,就设置成falsebreak; // 后续的循环就不需要进行了}

6.2.2 递归判断相邻两点的颜色是否一致

private boolean dfs(int v, int color){  //参数一:顶点   参数二:颜色visited[v] = true;colors[v] = color;//依次判断相邻顶点w的颜色for(int w: G.adj(v))if(!visited[w]){ //如果w没有被访问过,则进入判断if(!dfs(w, 1 - color)) //如果v的颜色是0,那么w的颜色应该是1。如果v的颜色是1,那么w的颜色应该是0.return false; //如果相邻的两个顶点颜色一样,那么就不是二分图}else if(colors[w] == colors[v]) //如果相邻的两个顶点颜色一样,那么就不是二分图return false;return true;
}

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

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

相关文章

【手写数据库toadb】语言解析器,编程语言是这样被解析理解,解析器利器flex和bison,解析树与逆波兰式

flex与bsion使用介绍 ​专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方…

安装插件失败,getaddrinfo ENOENT raw.githubusercontent.com 报错

报错如图 解决方法&#xff1a; 查看raw.githubusercontent.com的真实IP地址 点开网址 https://www.ipaddress.com/ &#xff0c;输入raw.githubusercontent.com&#xff0c;点击查询&#xff1a; 复制以下的ip 修改hosts文件 找到这个文件夹&#xff1a; C:\Windows\System32\…

MIPS指令集摘要

目录 MIPS指令R I J三种格式 MIPS五种寻址方式 立即数寻址 寄存器寻址 基址寻址 PC相对寻址 伪直接寻址 WinMIPS64汇编指令 助记 从内存中加载数据 lb lbu lh lhu lw lwu ld l.d lui 存储数据到内存 sb sh sw sd s.d 算术运算 daddi daddui dadd…

Java中静态常量和枚举类的区别

在项目中我们有时候会使用常量、静态常量以及枚举&#xff0c;那么他们有什么区别呢&#xff1f;我们先看几个例子&#xff1a; 若依框架中使用的常量&#xff1a; /** 正常状态 */public static final String NORMAL "0";/** 异常状态 */public static final Stri…

绿盾控制台如何给未授权终端分配相应权限

环境&#xff1a; 绿盾控制台7.0 问题描述&#xff1a; 绿盾控制台如何给未授权终端分配相应权限 解决方案&#xff1a; 1.进入桌面管理系统 2.通过终端号&#xff0c;找到未授权终端下面&#xff0c;选择相应的未授权终端 3.点击鼠标右键&#xff0c;选择分配授权模块 4.下…

01认识微服务

一、微服务架构演变 1.单体架构 将所有的功能集中在一个项目开发&#xff0c;打成一个包部署。优点架构简单&#xff0c;部署成本低。缺点耦合度高&#xff0c;不利于大型项目的开发和维护 2.分布式架构 根据业务功能对系统进行拆分&#xff0c;每个业务模块作为独立的项目…

修改ConsoleApplication17_2项目实现oss上线

首先创建号oss&#xff0c;上传文件&#xff0c;复制临时链接 木马内写 可以看到能成功上线但是有个问题就是占用cpu大小为9%左右&#xff0c;这里我用的是腾讯云oss实现的&#xff0c;用阿里云oss实现也是9%左右 我再次进行url的aes加密 还是百分之9左右&#xff0c; 这里…

npm publish发布到在线仓库时,提示:Scope not found

当npm publish发布时&#xff0c;控制台提示&#xff1a;Scope not found&#xff0c;具体错误信息如下&#xff1a; npm notice npm ERR! code E404 npm ERR! 404 Not Found - PUT https://registry.npmjs.org/xxx%2fxxx - Scope not found npm ERR! 404 npm ERR! 404 xxx/xx…

Spring源码解析——事务的回滚和提交

正文 上一篇文章讲解了获取事务&#xff0c;并且通过获取的connection设置只读、隔离级别等&#xff0c;这篇文章讲解剩下的事务的回滚和提交。最全面的Java面试网站 回滚处理 之前已经完成了目标方法运行前的事务准备工作&#xff0c;而这些准备工作最大的目的无非是对于程…

[计算机提升] 快捷方式与硬链接

1.7 快捷方式与硬链接 1.7.1 快捷方式(符号链接) 在Windows系统中&#xff0c;快捷方式是指一个特殊的文件或图标&#xff0c;它提供了方便的访问其他文件、文件夹、应用程序或网站的方式。快捷方式可以视为一个指向其他位置的链接或引用。 快捷方式被创建时&#xff0c;会关…

Rust 中的String与所有权机制

文章目录 一、string二、所有权2.1 所有权与作用域2.2 对所有权的操作2.2.1 转移2.2.3 拷贝2.2.3 传递 2.3 引用2.3.1 借用2.3.2 可变引用 一、string 之前学习过 Rust 只有几种基础的数据类型&#xff0c;但是没有常用的字符串也就是String&#xff0c;今天来学习一下 String…

【单元测试】--单元测试最佳实践

一、单元测试代码风格 编写单元测试代码时&#xff0c;遵循一致的风格和最佳实践是非常重要的&#xff0c;因为它有助于提高代码的可读性、可维护性和可靠性。以下是一些常见的单元测试代码风格和最佳实践&#xff1a; 命名约定&#xff1a; 测试方法的名称应当清晰、描述性&…

C++初阶(五)类和对象

文章目录 一、C两大类型二、类的6个默认成员函数三、构造函数1、概念2、特性1、构造函数自动调用特性演示2、无参有参调用两种情况演示3、函数重载演示4、默认构造函数组成及演示5、内置类型成员不初始化的补丁演示 3、析构函数1、概念2、特性1、代码演示2、析构两种情况 4、构…

使用vscode调试ffmpeg源码

ffmpeg的编译配置 # --enable-debug 设置为调试级别 # --disable-stripping 如果不加此选项&#xff0c;会strip去掉符号信息 ./configure --prefix{output_path} --enable-debug --disable-stripping make -j10VSCode的配置 将以下文件对比替换工程.vscode目录下的相同文件 …

vsCode git 修改、清空、重置、保存账号名密码

1、保存账号名密码&#xff0c;之后拉取代码都不用重新输入&#xff1a; git config --global credential.helper store 2、查看git用户名&#xff1a; git config user.name 3、清空所有的用户名和密码&#xff1a; git config --system --unset credential.helper 4、清…

Django实现音乐网站 (21)

使用Python Django框架做一个音乐网站&#xff0c; 本篇音乐播放器功能完善及原有功能修改。 目录 播放列表修改 视图修改 删除、清空播放器 设置路由 视图处理 修改加载播放器脚本 模板修改 脚本设置 清空功能实现 删除列表音乐 播放列表无数据处理 视图修改 播放…

目标检测YOLO实战应用案例100讲-基于改进YOLO v7的智能振动分拣系统开发(续)

目录 3.2 引入EIOU损失函数 3.2.1 CIOU损失函数 3.3.2 基于Focal-EIOU损失函数的网络优化 ​编辑

【算法】TOP101-二叉树篇(持续更新ing)

文章目录 1. JZ36 二叉搜索树与双向链表2. 100. 相同的树3. 572. 另一棵树的子树4. BM26 求二叉树的层序遍历5. BM33 二叉树的镜像6. BM40 重建二叉树7. 106. 从中序与后序遍历序列构造二叉树 1. JZ36 二叉搜索树与双向链表 JZ36 二叉搜索树与双向链表 解题思路: 由题目可知,…

【uniapp/uView】解决消息提示框悬浮在下拉框之上

需要实现这样的效果&#xff0c;即 toast 消息提示框在 popup 下拉框之上&#xff1a; 解决方法&#xff0c;把 <u-toast ref"uToast" /> 放在 u-popup 里面即可&#xff0c;这样就可以提升 toast 的优先级&#xff1a; <!-- 弹出下拉框 --><u-popu…

MySQL数据的基础语法

MySQL 是一种强大的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它使用 SQL&#xff08;Structured Query Language&#xff09;来管理和操作数据。以下是 MySQL 数据库的基础 SQL 语法&#xff0c;包括创建数据库、创建表、插入、查询、更新和删除数据等基…