12.7图欧拉回路与路径,图的一些性质,存储方式,图的遍历(有向图无向图BFSDFS)

欧拉回路与欧拉路径

存在条件

无向图存在欧拉回路的充要条件
一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。
无向图存在欧拉路径的充要条件
当且仅当该图顶点度数为奇数的点的个数为0或者2。

欧拉定理二:
如果一个无向图有2n个奇顶点,那么它至少需要n笔画成。

有向图存在欧拉回路的充要条件
一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图

B是要回到出发点,即欧拉回路;A是一笔画即可

当前这个图4个结点度数都为奇数,添一条边使2个结点的奇数度数的结点为偶数,故添一条边会使奇数的点个数变为2,可构成欧拉路径

判断欧拉回路代码


int n, m, degree[1001];
int s, t;
while (cin >> n) {bool flag = 1;for (int i = 0; i < n; i++) {degree[i] = 0;}cin >> m;for (int i = 1; i <= m; i++) {cin >> a >> b;degree[a]++;degree[b]++;}for (int i = 0; i < n; i++) {if (degree[i] % 2 != 0) {flag = 0;break;}}cout << flag ? "YES" : "NO";
}

这段代码是一个用来判断无向图是否为欧拉图的程序。

主要流程如下:
- 声明了整型变量 `n` 和 `m`,以及一个整型数组 `degree` 用来记录每个顶点的度数
- 使用循环不断读入顶点的数量 `n`,如果 `n` 不等于 0,则继续执行程序。(每个测试样例)
- 在每个循环中,首先读入边的数量 `m`。
- 设置一个标志变量 `flag` 初始化为 1。
- 使用 `memset` 函数将 `degree` 数组初始化为 0。
- 使用一个循环读入每条边,并更新对应顶点的度数。
- 再使用一个循环遍历每个顶点,如果某个顶点的度数为奇数,则将 `flag` 置为 0。
- 最后,输出 `flag` 的值,表示是否为欧拉图。

整个程序的目的是判断给定的无向图是否为欧拉图,其中欧拉图的定义是每个顶点的度数都为偶数。如果是欧拉图,则输出 1,否则输出 0。

这里是默认结点编号从0开始,如果从1开始则需要小小修改一下。

图有两个重要参数,一个是顶点,一个是边数

只有存在边时,才会使顶点的度发生改变

图的性质

图的存储

图有两个重要参数,一个是顶点,一个是边数

只有存在边时,才会使顶点的度发生改变

数组可以用来存储结点,也可以用来存储边

定义结构体也可以定义结点或边

邻接表

在有向图中,只有可以达到才会是邻居

struct node{vector<int> v;
}a[MAXN];for (int i = 1 ; i <= m ; i ++) {int u , v;scanf("%d %d", &u , &v);a[u].v.push_back(v);a[v].v.push_back(u);	
} 
return 0;

有m条边。这里是无向图的邻接表法

链式前向星

edge的数组下标编号代表边的编号,按照边的输入顺序依次存储。

head数组下标代表图的结点的编号,head[u]表示以u为起点的一条边

struct edge{int to , nxt , w;
};
edge a[MAXN];
void add(int u , int v , int w) {a[cnt].w = w;a[cnt].to = v;a[cnt].nxt = head[u];head[u] = cnt ++;
}

这段代码是用来实现添加边的函数。

- 定义了一个结构体 `edge`,其中包含三个整数变量 `to`、`nxt` 和 `w`,分别表示边的终点、下一条边的索引和边的权重。
- 声明了一个名为 `a` 的结构体数组,作为表示图的边集合,大小为 MAXN。
- 声明了一个静态整数变量 `cnt`,用于记录边的数量
- 声明了一个名为 `head` 的整数数组,用于记录每个顶点的最近新插入边的索引
- 定义了一个名为 `add` 的函数,用于添加一条从顶点 `u` 到顶点 `v` 的边,并设置边的权重为 `w`。
- 在 `add` 函数中,将当前边的权重、终点和下一条边的索引分别赋值给 `a[cnt].w`、`a[cnt].to` 和 `a[cnt].nxt`,然后将 `cnt` 的值赋给 `head[u]`,即将当前边的索引存储在顶点 `u` 的第一条边上。
- 最后,将 `cnt` 的值递增一次。

通过调用 `add` 函数,可以在图中添加一条从顶点 `u` 到顶点 `v` 的边,同时设置该边的权重为 `w`。
 

图的遍历

求连通分量

在遍历过程中通过vis数组,以及一个cnt计数可以确定连通分量

有向图DFS

void dfs(int k) {if (vis[k]) return;vis[k] = 1;printf("%d ", k);for (set<int>:: iterator it = st[k].begin() ; it != st[k].end() ; it ++) {dfs(*it);}
}
for (int i = 1 ; i <= m ; i ++) {int u , v;scanf("%d %d", &u , &v);st[u].insert(v);
} 
dfs(1);
for (int i = 1 ; i <= n ; i ++) {if (!vis[i]) dfs(i);
}

由于是有向图,在邻接表法中,只要写st[u].insert[v] 

使用一个循环遍历顶点 k 对应的邻接集合 st[k],对于每个相邻的顶点 v,递归调用 dfs 函数进行深度优先搜索。

在主函数中,使用一个循环读取 m 条边的信息,并将每条边的尾部顶点插入到起始顶点对应的邻接集合 st[u] 中。

接着,调用 dfs(1),以顶点 1 为起点进行深度优先搜索。该步骤将遍历与顶点 1 相连的所有顶点。

最后,使用一个循环遍历所有顶点,如果某个顶点尚未被访问过,则调用 dfs 函数对该顶点进行深度优先搜索。这样可以确保遍历图中的所有连通分量。

通过vis数组可以确定图的连通分量

有向图BFS

void bfs(int k) {q.push(k);while(!q.empty()) {int x = q.front();q.pop();if (vis[x]) continue;vis[x] = 1;printf("%d ", x);for (set<int>:: iterator it = st[x].begin() ; it != st[x].end() ; it ++) {q.push(*it);}}
}
for (int i = 1 ; i <= m ; i ++) {int u , v;scanf("%d %d", &u , &v);st[u].insert(v);	
} 
bfs(1);
for (int i = 1 ; i <= n ; i ++) {if (!vis[i]) bfs(i);
}

无向图BFS

void bfs() {q.push(rt);while(!q.empty()) {int x = q.front();q.pop();if (vis[x]) continue;vis[x] = 1;printf("%d ", x);for (int i = 1 ; i <= n ; i ++) {if (adj[x][i]) {q.push(i);}}}
}
for (int i = 1 ; i <= m ; i ++) {int u , v;scanf("%d %d", &u , &v);adj[u][v] = 1;adj[v][u] = 1;	
} 

无向图和有向图最主要区别是,采用数据结构不一样。有向图用集合,可以自动从小到大,无向图用矩阵,定一结点,遍历以该结点为起点的矩阵行

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

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

相关文章

sql注入漏洞--MYSQL两种思路

在学习之前&#xff0c;先自己搭建了一个网站 在前端可以实现与后端数据库的交互查询 创建一个数据库名为wy&#xff0c;表名为users 建立字段&#xff0c;定义类型 插入数据 INSERT INTO users(name, password,photo, money) VALUES ("DuZZ",123456,11,100); IN…

(三)基于高尔夫优化算法GOA求解无人机三维路径规划研究(MATLAB代码)

一、无人机模型简介&#xff1a; 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献&#xff1a; [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、高尔夫优化算法GOA简介 高尔夫优化算法…

虚拟数据优化器VDO

本章主要介绍虚拟化数据优化器。 什么是虚拟数据优化器VDO创建VDO设备以节约硬盘空间 了解什么是VDO VDO全称是Virtual Data Optimize&#xff08;虚拟数据优化)&#xff0c;主要是为了节省硬盘空间。 现在假设有两个文件file1和 file2&#xff0c;大小都是10G。file1和 f…

Retrofit嵌套请求与适配器

一、前言&#xff1a; 1. retrofit嵌套请求 在实际开发中&#xff0c;可能会存在&#xff1a;需要先请求A接口&#xff0c;在请求B接口的情况&#xff0c;比如进入“玩android”网页请求获取收藏文章列表&#xff0c;但是需要先登录拿到Cookie才能请求搜藏文章几口&am…

【web安全】文件包含漏洞详细整理

前言 菜某的笔记总结&#xff0c;如有错误请指正。 本文用的是PHP语言作为案例 文件包含漏洞的概念 开发者使用include&#xff08;&#xff09;等函数&#xff0c;可以把别的文件中的代码引入当前文件中执行&#xff0c;而又没有对用户输入的内容进行充分的过滤&#xff0…

添加新公司代码的配置步骤-Part3

原文地址&#xff1a;配置公司代码 概述 这是讨论创建新公司代码的基本标准配置步骤的第三篇博客。在第 1 部分中&#xff0c;我列出并讨论了企业结构中需要配置的项目。我随后提供了特定 FI 配置的详细信息。在本版本中&#xff0c;我将重点关注 SD 和 MM 模块。以下是这些博…

每日一题:LeetCode-11.盛水最多的容器

每日一题系列&#xff08;day 13&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

低代码——“平衡饮食”才是王道

文章目录 一、低代码的概念二、低代码的优点2.1. 高效率与快速开发2.2. 降低技术门槛2.3. 适用于快速迭代与原型开发 三、低代码的缺点3.1. 定制性不足3.2. 深度不足3.3. 可能导致技术债务 四、低代码开发的未来4.1. 深度定制化4.2. 智能化 五、低代码会替代传统编程吗&#xf…

Python Struct 模块:二进制数据的强大解析与打包工具

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Python中的struct模块是一个强大而灵活的工具&#xff0c;用于解析和打包二进制数据。本文将深入介绍struct模块的各个方面&#xff0c;通过丰富的示例代码&#xff0c;帮助读者更全面地理解和运用这一模块&…

参考信号速度变化存在跳跃时容易发生不稳定的阻抗调节

问题描述 当参考信号速度存在跳跃变化时&#xff0c;阻抗调节系统容易发生不稳定。这是因为阻抗调节系统需要根据参考信号的速度来调整其输出阻抗&#xff0c;以匹配负载阻抗&#xff0c;从而保持系统的稳定性。 当参考信号速度突然变化时&#xff0c;阻抗调节系统可能无法及…

C++新经典模板与泛型编程:用成员函数重载实现is_base_of

用成员函数重载实现is_base_of std::is_base_of是一个C 11标准中用于判断某个类是否是另一个类父类的类模板。 #include "killCmake.h"#include<string>using namespace std;class A { };class B : public A { public:B(int x): x_(x){} private:int x_; };/…

LinuxBasicsForHackers笔记 -- BASH 脚本

你的第一个脚本&#xff1a;“你好&#xff0c;黑客崛起&#xff01;” 首先&#xff0c;您需要告诉操作系统您要为脚本使用哪个解释器。 为此&#xff0c;请输入 shebang&#xff0c;它是井号和感叹号的组合&#xff0c;如下所示&#xff1a;#! 然后&#xff0c;在 shebang …