UNPKG

oi-wiki

Version:
128 lines (64 loc) 3.92 kB
## 图是怎么存的? ### 直接存边 什么意思呢?我们开一个数组,数组里每个元素是图的一条边。 这样做有个缺点,每次想要知道两个点之间是否有连边(或者说一条边是否存在),都需要在数组里进行一番查找。而且如果没有对边事先排序的话,就不能使用二分查找的方法($O(\log n)$),而是每次只能按顺序找($O(n)$),成本较高。 什么时候会用到这个方法呢?最简单的一个例子是使用 Kruskal 算法求 [最小生成树](/graph/mst) 的时候。 ### 邻接矩阵 邻接矩阵的英文名是 adjacency matrix。它的形式是 `bool adj[n][n]`,这里面 $n$ 是节点个数,$adj[i][j]$ 表示 $i$ 和 $j$ 之间是否有边。 如果边有权值,也可以直接用 `int adj[n][n]`,直接把边权存进去。 它的优点是可以在 $O(1)$ 时间内得到一条边是否存在,缺点是需要占用 $O(n^2)$ 的空间。对于一个稀疏的图(边相对于点数的平方比较少)来说,用邻接矩阵来存的话,成本偏高。 ### 邻接表 邻接表英文名是 adjacency list。它的形式是 `vector adj[n]`,用 `adj[i]` 存以 $i$ 为起点的边。 用 `vector` 无法科学地删除,所以常用 `list` 实现。 它的特点是可以用来按顺序访问一个结点的出边(或者入边)。 ### 前向星 为什么它搜不到英文名呢?因为是中国玩家乱搞出来的。 首先介绍一下链式前向星,本质上是用单向链表实现的邻接表。 形式上是一个结构体:`struct edge {edge *pre, int to;} *head[N], edge[M]'` 这个结构广泛出现于算法竞赛选手的代码中,编写简洁而且对于大多数题目效率足够高。 其中 `head[i]` 用来存以 $i$ 为起点的边,`edge` 数组是边表。 那么什么是前向星呢?事先把 `edge` 数组排个序即可。这里可以使用 [基数排序](basic/sort) 做到 $O(m)$。 ## 一些跟图有关的定义 ### 路径 path,是指一个边的序列,其中的边首尾相连。 ### 简单路径 simple path,是每条边只经过了一次的路径。 ### 回路 cycle,也称为 `环`,是起点和终点相同的路径。 ### 简单回路 图的定点序列中,除了起点和终点相同外,其余顶点不重复的回路。 ### 连通 #### 两个点连通 无向图中点 $u$ 和 $v$ 连通是指存在一条 $u$ 到 $v$ 的路径。 #### 图连通 如果无向图 $G$ 中任意两个节点连通,称其为是连通的。 ### 可达 有向图中点 $u$ 到 $v$ 可达是指存在一条 $u$ 到 $v$ 的路径。 ### [强连通](/graph/scc) 有向图 $G$ 强连通是指,$G$ 中任意两个节点连通。 ### [弱连通](/graph/bcc) 有向图 $G$ 弱连通是指,$G$ 中的所有边替换为无向边后,$G$ 为连通图。 ### 子图 选取一个节点的子集和边的子集构成的图。 #### 生成子图 选取的子图的节点和原图一样。 #### 导出子图 选取一个节点的子集,再选取这些节点相关联的边的集合构成的图。 #### 边导出子图 选取一个边的子集,再选取这些边相关联的节点的集合,构成的图。 #### 连通子图 (一个无向图的)连通的子图。 #### 连通分量 (一个无向图的)极大的连通子图。 【注】:极大是指添加任何节点或者边后都不再满足。 ### 稀疏图 $m = \Theta(n)$ 的图,或者指 $m$ 相对较小的图。 ### 稠密图 $m = \Theta(n^2)$ 的图,或者指 $m$ 相对较大的图。 ### 完全图 $m = \frac{n(n-1)}{2}$ 的简单无向图。 ### 路径的长度 一般来说,路径的长度在数值上等于路径的边数,或者如果边是带权的,则是路径的边权和。 ### [最短路径](/graph/shortest-path) 两个节点之间,长度最小的路径。 【注】:不一定存在,不一定唯一。