图及图的存储

目录

1.图的相关概念

2.图的存储

2.1.直接存法

 1.查询是否存在某条边

2.遍历一个点的所有出边

3..遍历整个图

应用

2.2.邻接矩阵

 1.查询是否存在某条边

2.遍历一个点的所有出边

3..遍历整个图

应用

2.3.邻接表

 1.查询是否存在某条边

2.遍历一个点的所有出边

3..遍历整个图

应用

2.4.链式前向星

应用


1.图的相关概念

在图论中,有一些核心概念和基本术语,这些概念对于理解和处理图结构非常重要。以下是一些常见的图论概念梳理:

有向图:

无向图:

1.图 (Graph):图是由点集合及连接这些点的边集合组成的数学结构。图的点通常称为“顶点”(vertices),而连接顶点的线或弧称为“边”(edges)。

2.简单图 (Simple graph)与完全图:简单图是没有重复边和重复顶点的图。也就是说,在简单图中,任何两个不同的顶点之间最多只有一条边,并且不存在顶点到边,除了自环。完全图是一种简单图,其中任意两个不同的顶点之间都有一条边。

3.自环 (Loop):自环是指顶点自身相连的边。即一个顶点与自身的一条边。

4.重边:重边是指在图中连接相同两个顶点的边,如果有两条或多条边连接同一个顶点对,则这些边称为重边。

5.点边关联:点边关联是指图中的每个顶点都与零条或多条边相关联。

6.边相邻,点相邻:边相邻:如果两条边共享一个顶点,则这两条边是边相邻的。点相邻:如果两个顶点之间存在一条边,则这两个顶点是点相邻的。

7.度 (Degree):顶点的度是指与该顶点相邻的边的数量。即连接到该顶点的边的条数。

8.孤立点 (Isolated vertex):孤立点是指度为零的顶点,即没有与其他顶点相连的顶点。

9.叶节点 (Leaf vertex):叶节点,也称为终端节点,是指度为1的顶点,即只与一个顶点相连的顶点。

10.偶点 (Even vertex):偶点是指度的度数为偶数的顶点。

11.奇点 (Odd vertex):奇点是指度的度数为奇数的顶点。

12.最小度 (Minimum degree):最小度是指图中所有顶点中最小的度值。

13.最大度 (Maximum degree):最大度是指图中所有顶点中最大的度值。

14.出度 (Outdegree)与入度 (Indegree):出度是指从某个顶点出发的边的数量,入度是指指向某个顶点的边的数量。

15. k−正则图k−Regular Graph):k−正则图是指所有顶点的度都是k的图。

16.同构 (Isomorphism):如果两个图在结构上完全相同,即它们具有相同的顶点和边,并且这些边连接相同的顶点对,那么这两个图是同构的。

17.途径 (Walk):图中的一条路径是一系列顶点的序列,其中每一对相邻顶点之间都有一条边或弧。路径可以有方向或无方向。

18.迹 (Trail):迹是图中的一条路径,除了允许重复经过相同的边,不允许经过相同的顶点。

19.路径 (Path):路径是图中的一条无重复边的序列,每个顶点只一次,除了第一个和最后一个顶点。

20.回路 (Circuit)与简单回路 (Simple circuit)
- 回路或环是指从一个顶点出发,经过一系列边和顶点,最终回到出发点的路径。
- 简单回路是指没有重复边和顶点的回路。

21.图的连通性 (Connected)与连通图 (Connected graph)以及连通分量 (Connected component)
- 连通性是指图中任意两个顶点之间都存在一条路径。
- 连通图是指图中任意两个顶点都是连通的。
- 连通分量是指在一个图中,所有连通顶点的集合。

22.导出子图/诱导子图 (Induced subgraph):导出子图是指原图中由一组顶点和它们之间的边组成的子图,而诱导子图是指原图中由一组顶点所形成的子图及其所有相邻边。

23.补图:补图是指原图的所有顶点以及原图中没有的边组成的图。

24.一些特殊的无向简单图
- 星图:一个中心顶点和其余顶点连接而成的图。
- 圈图:一个闭合的顶点序列,每个顶点都与其他顶点相连。

25.无向简单图有关的二元运算(交、并、和、笛卡尔积)

- 交(Intersection):图G和H的交是由G和H中共同的边组成的图。如果两条边在G和H中都存在,那么它们也存在于交图中。
- 并(Union):图G和H的并是由G和H中的所有边组成的图,包括G中的边和H中的边,但不包括G和H的交中的边。
- 和(Symmetric Difference):图G和H的和是由G和H中不共同的边组成的图。如果一条边在G中但不在H中,或者在H中但不在G中,那么这条边就在和图中。
- 笛卡尔积(Cartesian Product):图G和H的笛卡尔积是由G的每个顶点与H的每个顶点相连组成的图。如果G有v个顶点,H有w个顶点,那么G和H的笛卡尔积有vw个顶点,每个顶点都是由一个来自G的顶点和一个来自H的顶点组成的。

26.点割集与边割集
- 点割集:如果移除图中的一个顶点,会导致原图不再连通,那么这个顶点就是一个点割。所有这样的顶点的集合称为点割集。
- 边割集:如果移除图中的一条边会导致原图不再连通,那么这条边就是一个边割。所有这样的边的集合称为边割集。

27.树、森林、最小生成树
- 树是一种没有环的无向图,它是连通的,并且有n个顶点就有n-1条边。
- 森林是由零个或多个树组成的图。
- 最小生成树是指在一个加权连通图中,权值之和最小的生成树。

28.最短路径
- 最短路径是指在加权图中,连接两个顶点的路径中权值之和最小的路径。

29.拓扑排序
- 拓扑排序是指对有向无环图(DAG)的所有顶点进行排序,使得对于图中的每条有向边(u,v),顶点u在排序中顶点v之前。这样的排序是唯一的,如果存在多个DAG可以有多个拓扑排序。

2.图的存储

2.1.直接存法

使用一个数组来存边,数组中的每个元素都包含一条边的起点与终点(带边权的图还包含边权)(或者使用多个数组分别存起点,终点和边权)。空间复杂度:O(m)。

struct Edge {int u, v;
};
vector<Edge> e;

 1.查询是否存在某条边

struct Edge {int u, v;
};
vector<Edge> e;
int m;//有m条边
bool find_edge(int u, int v) {for (int i = 1; i <= m; i++) {if (e[i].u == u && e[i].v == v) {return true;}}return false;
}

算法复杂度为:O(m);

2.遍历一个点的所有出边

struct Edge {int u, v;
};
vector<Edge> e;
int m;//有m条边
void find_outedge(int u) {for (int i = 1; i <= m; i++) {if (e[i].u == u) {//对这个点的出边的操作}}
}

算法复杂度:O(m);

3..遍历整个图

struct Edge {int u, v;
};
vector<Edge> e;
int m, n;//m条边,n个点
vector<bool> vis(n + 1, false);
void dfs(int u) {if (vis[u]) return;//访问过返回vis[u] = true;//u访问过for (int i = 1; i <= m; i++) {if (e[i].u == u) {dfs(e[i].v);//递归遍历下一个节点}}
}

算法复杂度:O(nm);

应用

由于直接存边的遍历效率低下,一般不用于遍历图。

在 Kruskal 算法 Kruskal 算法中,由于需要将边按边权排序,需要直接存边。

在有的题目中,需要多次建图(如建一遍原图,建一遍反图),此时既可以使用多个其它数据结构来同时存储多张图,也可以将边直接存下来,需要重新建图时利用直接存下的边来建图。

2.2.邻接矩阵

使用一个二维数组 adj 来存边,其中 adj[u][v] 为 1 表示存在u到v的边,为 0 表示不存在。如果是带边权的图,可以在 adj[u][v] 中存储u到b的边的边权。空间复杂度:O(n^{2}) 。

vector<vector<bool> > adj;

 1.查询是否存在某条边

vector<vector<bool> > adj;
bool find_edge(int u, int v) { return adj[u][v]; }

算法复杂度为:O(1);

2.遍历一个点的所有出边

struct Edge {int u, v;
};
vector<vector<bool> > adj;
int n;//有n个点
void find_outedge(int u) {for (int i = 1; i <= n; i++) {if (adj[u][n]) {//对这个点的出边的操作}}
}

算法复杂度:O(n);

3..遍历整个图

int m, n;//m条边,n个点
vector<bool> vis(n + 1, false);
vector<vector<bool> > adj;
void dfs(int u) {if (vis[u]) return;//访问过返回vis[u] = true;//u访问过for (int v = 1; v <= n; i++) {if (adj[u][v]) {dfs(v);//递归遍历下一个节点}}
}

算法复杂度:O(n^{2});

应用

邻接矩阵只适用于没有重边(或重边可以忽略)的情况。

其最显著的优点是可以O(1)查询一条边是否存在。

由于邻接矩阵在稀疏图上效率很低(尤其是在点数较多的图上,空间无法承受),所以一般只会在稠密图上使用邻接矩阵。

2.3.邻接表

使用一个支持动态增加元素的数据结构构成的数组,如 vector<int> adj[n + 1] 来存边,其中 adj[u] 存储的是点u的所有出边的相关信息(终点、边权等)。空间复杂度:O(m)。用d^{+}(v)代指点v的出度,即以v为出发点的边数。

vector<vector<int> > adj;//以存终边为例 

 1.查询是否存在某条边

vector<vector<int> > adj;//以存终边为例 
bool find_edge(int u, int v) {for (int i = 0; i < adj[u].size(); i++) {if (adj[u][i] == v) {return true;}}return false;
}

算法复杂度为:O(d^{+}(v));(如果事先进行了排序就可以使用二分查找做到O(log(d^{+}(v)))。

2.遍历一个点的所有出边

vector<vector<int> > adj;//以存终边为例 
void find_outedge(int u) {for (int i = 0; i < adj[u].size(); i++) {adj[u][i]//对这个点的出边的操作}
}

算法复杂度:O(d^{+}(v));

3..遍历整个图

int m, n;//m条边,n个点
vector<bool> vis(n + 1, false);
vector<vector<int> > adj;
void dfs(int u) {if (vis[u]) return;//访问过返回vis[u] = true;//u访问过for (int i = 0; i < adj[u].size(); i++) dfs(adj[u][i]);//递归遍历下一个节点
}

算法复杂度:O(n + m);

应用

存各种图都很适合,除非有特殊需求(如需要快速查询一条边是否存在,且点数较少,可以使用邻接矩阵)。

尤其适用于需要对一个点的所有出边进行排序的场合。

2.4.链式前向星

本质上是用链表实现的邻接表,核心代码如下:

// head[u] 和 cnt 的初始值都为 -1
void add(int u, int v) {nxt[++cnt] = head[u];  // 当前边的后继head[u] = cnt;         // 起点 u 的第一条边to[cnt] = v;           // 当前边的终点
}
// 遍历 u 的出边
for (int i = head[u]; i != -1; i = nxt[i]) {int v = to[i];
}
#include <iostream>
#include <vector>using namespace std;int n, m;
vector<bool> vis;
vector<int> head, nxt, to;void add(int u, int v) {nxt.push_back(head[u]);head[u] = to.size();to.push_back(v);
}bool find_edge(int u, int v) {for (int i = head[u]; i != -1; i = nxt[i]) {  if (to[i] == v) {return true;}}return false;
}void dfs(int u) {if (vis[u]) return;vis[u] = true;for (int i = head[u]; i != -1; i = nxt[i]) dfs(to[i]);
}int main() {cin >> n >> m;vis.resize(n + 1, false);head.resize(n + 1, -1);for (int i = 1; i <= m; ++i) {int u, v;cin >> u >> v;add(u, v);}return 0;
}

各个算法复杂度与邻接矩阵相同

应用

存各种图都很适合,但不能快速查询一条边是否存在,也不能方便地对一个点的出边进行排序。

优点是边是带编号的,有时会非常有用,而且如果 cnt 的初始值为奇数,存双向边时 i ^ 1 即是 i 的反边(常用于网络流)。

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

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

相关文章

RabbitMQ应用场景

1、异步处理 假设想象一下我们做一个商城项目&#xff0c;在用户支付模块中&#xff0c;可能会涉及到其它业务&#xff0c;比如&#xff1a;积分折扣、消费券、短信验证等功能。我们传统的执行步骤是逐步执行&#xff0c;也就是说当用户点击支付 ----> 积分折扣 ----> 消…

Project_Euler-10 题解

Project_Euler-10 题解 题目 思路 没有思路&#xff0c;一个线性筛秒了,只不过最近没发博客有点手生哈哈哈哈哈。 代码 /*************************************************************************> Author: Royi > Mail: royi990001gmail.com > From: > Lan…

2014-2023年上市银行华证ESG评级数据/银行ESG评级数据

2014-2023年上市银行华证ESG评级数据/银行ESG评级数据 1、时间&#xff1a;2014-2023年 2、指标&#xff1a;证券代码、证券简称、华证ESG评级 3、来源&#xff1a;原始数据整理自wind 4、范围&#xff1a;42家银行&#xff1a; 苏农银行、中信银行、贵阳银行、中国银行、…

力扣---接雨水---单调队列+动态规划+双指针

题目&#xff1a; 单调队列思想&#xff1a; 没有思路的小伙伴可以先把这个想清楚哦&#xff1a;力扣hot10---大根堆双端队列-CSDN博客 从上面的图就可以发现&#xff0c;如果柱子呈递减序列&#xff0c;那么不会接到雨水&#xff0c;只要有一个小凸起柱子&#xff0c;那么这个…

智慧城市的前景:数字孪生技术在智慧城市中的应用前景

目录 一、引言 二、数字孪生技术及其在智慧城市中的应用概述 三、数字孪生技术在智慧城市中的应用前景 1、城市规划与仿真模拟 2、智能交通与出行服务 3、智慧环保与可持续发展 4、智慧公共服务与社会治理 5、智慧能源与绿色建筑 四、数字孪生技术在智慧城市中的挑战与…

SpringCloud(21)之SpringCloud Alibaba Nacos实战应用

一、Nacos安装 1.1 Nacos概述 Nacos是Alibaba微服务生态组件中的重要组件之一&#xff0c;主要用它实现应用的动态服务发现、配置管理、 服务管理。Nacos discovery alibaba/spring-cloud-alibaba Wiki GitHub Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简…

Oracle.xs.dll‘ for module DBD::Oracle: load_file:找不到指定的模块

安装Ora2pg时,碰到 异常现象 D:\ProgramFiles\ora2pg>ora2pg -t show_report --estimate_cost -c ora2pg_conf.dist install_driver(Oracle) failed: Cant load D:/ProgramFiles/strawberry/perl/site/lib/auto/DBD/Oracle/Oracle.xs.dll for module DBD::Oracle: load_fil…

vulhub靶场-matrix-breakout-2-morpheus

下载&部署 从官网中下载 https://www.vulnhub.com/entry/matrix-breakout-2-morpheus,757/ 下载完成后&#xff0c;在vmware中打开&#xff0c;选择刚刚下载的ova文件 vmware打开文件后需要将刚导入的机器重新启动 再检查下网卡是否是和kali在同一张网卡下就可以开始打靶了…

设计模式学习笔记 - 规范与重构 - 5.如何通过封装、抽象、模块化、中间层解耦代码?

前言 《规范与重构 - 1.什么情况下要重构&#xff1f;重构什么&#xff1f;又该如何重构&#xff1f;》讲过&#xff0c;重构可以分为大规模高层重构&#xff08;简称 “大型重构”&#xff09;和小规模低层次重构&#xff08;简称 “小型重构”&#xff09;。大型重构是对系统…

谷粒商城【成神路】-【10】——缓存

目录 &#x1f9c2;1.引入缓存的优势 &#x1f953;2.哪些数据适合放入缓存 &#x1f32d;3.使用redis作为缓存组件 &#x1f37f;4.redis存在的问题 &#x1f9c8;5.添加本地锁 &#x1f95e;6.添加分布式锁 &#x1f95a;7.整合redisson作为分布式锁 &#x1f697…

【教程】使用小米换机来迁移数据

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 1、在新旧手机上都下载安装小米换机app&#xff1a;小米换机-小米应用商店 2、在新手机上&#xff0c;选择旧手机类型 3、授予权限 4、在旧手机上&#xff0c;授予权限 4、输入锁屏密码 5、选择发现的新手机 6、等…

EMC整改

EMC包括EMI和EMS&#xff0c;其中EMI由辐射干扰RE、传导干扰CE、谐波电流Harmonics、闪烁Flicker组成&#xff0c;EMS由静电抗扰度ESD、电快速瞬态脉冲群EFT、电压跌落DIP、传导抗扰度CS、辐射抗扰度RS、浪涌抗扰度surge、工频磁场抗扰度PMS。新产品生产出来但凡要做认证&#…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:NavDestination)

作为子页面的根容器&#xff0c;用于显示Navigation的内容区。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 该组件从API Version 11开始默认支持安全区避让特性(默认值为&#xff1a;expandSaf…

嘿!AI 编码新玩法上线!

随着 AI 智能浪潮到来&#xff0c;AI 编码助手成为越来越多开发者的必备工具&#xff0c;将开发者从繁重的编码工作中解放出来&#xff0c;极大地提高了编程效率&#xff0c;帮助开发者实现更快、更好的代码编写。 通义灵码正是这样一款基于阿里云通义代码大模型打造的智能编码…

Java学习笔记------拼图游戏

图形化界面GUI GUI&#xff1a;Graphical User Interface&#xff08;图像用户接口&#xff09;&#xff0c;指采用图形化的方式显示操作界面 两套体系&#xff1a;AWT包中和Swing包中 组件 JFrame&#xff1a;最外层的窗体 JMenuBar&#xff1a;最上层菜单 JLaber&#…

java继承,接口,抽象类

目录 目录 1 继承的含义 2 继承的好处 3使类与类之间产生了关系。 看这里继承-------我的理解 代码部分 接口 代码 抽象类 代码 各位友友们大家好呀&#x1f60a;&#xff01; 今天让我们继续回顾java&#xff0c;看看java中的抽象类以及接口继承是什么&#x1f914…

如何精确计算 π ?

如何精确计算 π &#xff1f; 01 原本是要回顾一下第六章内容&#xff0c;也就是“间隔性重复”。但我已经迫不及待&#xff0c;想要知道如何精确计算 π &#xff0c;因此&#xff0c;我们快走一步&#xff0c;来探讨一下 π 的计算。 对于 π 的计算&#xff0c;我从学校时…

浪潮信息数据中心管理平台InManage升级发布 新增三大场景功能

在AIGC应用日益广泛的当下&#xff0c;浪潮信息聚焦AIGC在数据中心运维管理中面临的难题&#xff0c;进一步通过技术创新升级功能及体验&#xff0c;为AIGC的高效应用创造了良好的基础。近日&#xff0c;浪潮信息数据中心管理平台InManage升级发布&#xff0c;新增资产数字化管…

智慧城市的未来:利用数字孪生技术推动智慧城市的智能化升级

目录 一、引言 二、数字孪生技术概述 三、数字孪生技术在智慧城市中的应用 1、城市规划与建设 2、城市管理与运营 3、公共服务与民生改善 4、应急管理与灾害防控 四、数字孪生技术推动智慧城市的智能化升级的价值 1、提高城市管理的智能化水平 2、优化城市资源配置 …

答题pk小程序源码技术大解析

答题pk小程序源码解析 在数字化时代&#xff0c;小程序因其便捷性、即用性而受到广泛欢迎。其中&#xff0c;答题pk小程序更是成为了一种寓教于乐的现象。它不仅为用户提供了趣味性的知识竞技平台&#xff0c;还为企业、教育机构等提供了互动营销和知识传播的新途径。本文将对…