图论基础知识

English Practice: 图论(Graph Theory)

在 USACO 上做题发现的,感觉还不错,就翻译了过来。正好练习一下自己的英文水平。

有兴趣的朋友们可以在网上找一下英文原文。

此翻译转载请注明来源. hi.baidu.com/foreverbell_

图论(Graph Theory)

——译 By ForeverBell[PG]

什么是(graph)

通常地说,一个图是这样的:
* 所有顶点(vertices) V 的集合;
* 所有(edges) E 的集合所构成的。

把顶点当做“地点”,那么所有顶点的集合就是所有地点的集合。按照这种比喻,边就可以看做连接每对地点之间的“路径”,所有边的集合就是所有路径的集合。


表示

图通常被用那种类比的方法表示,顶点是点或者圆圈,边是连接它们的线。



在这个例图中,V = {1, 2, 3, 4, 5, 6} ,并且E = {(1,3), (1,6), (2,5), (3,4), (3,6)}。

每一个顶点是集合 V 的一个成员。一个顶点有时候被叫做节点(node)

每一条边是集合 E 的一个成员。注意,有些顶点并不会有边和其他的顶点相连。这样的顶点被称是“孤立”的。

有时候,边是与数值相关联的,比如说长度或费用;这样的图被称作边权图(edge-weighted graphs),或者带权图(weighted graphs),这些被边关联的数值叫做边的(weight)。类似地,我们还定义点权图(node-weighted graphs)


图论的例题

奶牛的电信(Telecowmunication,USACO Championship 1996)

描述:给定一个电脑的集合,和连接所有电脑的电缆的集合,至少需要破坏多少台电脑,才能使给定的2台电脑不能连线?(给定的2台电脑不用破坏。)
图:图的顶点对应电脑,边即对应着电缆。

骑马修栅栏(Riding The Fences)
描述:农民约翰拥有大量的栅栏,他必须定期检查栅栏的完好。他时刻留意着栅栏们交点的位置,并记录了栅栏每个相交点的编号,以及与相交点相连的栅栏的编号。每一个栅栏与2个点相连。在某些交点,交点可能只是唯一一个栅栏的终点。
给定栅栏的布局,计算是否有一条路,能让农民约翰能骑马经过所有的栅栏,而不经过同一栅栏2次以上。农民约翰可以在任意一个地方开始和结束,但不能跨越它的场地(即,他唯一穿过2个交点的路只能沿着栅栏)。如果有这样的路径,就输出它。
图:农民约翰从交点出发,并经过所有栅栏一次。所以,图的顶点就是交点,边即栅栏。

Knight moves
描述:给定一个8*8的棋盘,至少需要多少的骑士,使棋盘上的每一个点都可以被至少一个骑士攻击到。
图:这个图比较难以表述,棋盘上的每一格被看做一个顶点。如果一个骑士可以从一格攻击到另一格,则这2个格就可被称作有边相连。

穿越栅栏(Overfencing [Kolstad & Schrijvers, Spring 1999 USACO Open])
描述:农民约翰在田野上建造了一个巨大的迷宫,他在留出了2个栅栏作为迷宫的2个“出口”。这个迷宫是一个“完美”的迷宫;你可以在里面任意一个地方,寻找到一条走出迷宫的路径。
给定迷宫的布局,计算从一个最“糟糕”的点走出迷宫需要的步数(即从该点以最优的方式走到最近的出口,所需的步数仍然是最多的)。
一个 W=5,H=3 的迷宫如下所示:
     +-+-+-+-+-+
     |         |
     +-+ +-+ + +
     |     | | |
     + +-+-+ + +
     | |     | 
     +-+ +-+-+-+
图:每一个格子都是一个顶点,如果相邻的2个格子之间,没有被墙分开,这2个格子就是有边相连。


术语

让我们再看第一个例图。


如果一条边的起点和终点都是同一个顶点(form (u,u)),这条边被称为环边(self-loop),此例图中没有环边。

简单(simple) 图是指在边集 E 中,没有环图,且一条边不重复出现的图。如果图中多次包含了同一条边,或者包含环边,这种图被称作复杂图(multigraph)。我们的讨论中,图都是简单图,例图就是一个简单图。

边(u, v)是连接(incident)了顶点 u 和顶点 v。例如,边(1,3)连接了顶点3。

顶点的(degree)是连接到该顶点的边的个数,例图中,顶点3的度数是3,同时顶点4的度数是1。

如果顶点 u 和 v 被一条边相连,那么 u 和 v 就是相连(adjacent)。例图中,顶点2与顶点5相连。

如果边的总数小于可能边的总数 ((N x (N-1))/2),那么这个图是稀疏(sparse),否则就是稠密(dense)。给定图是稠密的还是稀疏的,没有明确的界定。


有向图(Directed Graph)

上面所介绍的图都是无向(undirected),边都是“双向”的。如果我们能从顶点1到顶点3,那么我们也能从顶点3到顶点1。换句话说,如果边集中存在边(1, 3),那么也存在边(3, 1)。

但有时候图是有向的,在这种情况下,边是有方向的,这种边也被称作(arcs)

有向图被带上箭号来表示方向。



每个顶点的出度(out-degree)是从该顶点开始的弧的条数。每个顶点的入度(in-degree)是在该顶点结束的弧的的条数。例图中,顶点6的入度数是2,出度数是1。

一个图被假定为无向图,除非特别要求说明是有向图。


路径(Paths)

从顶点 u 到顶点 x的路径被定义为:顶点序列(v 0, v 1, ..., v k),而且v 0 = u,v k = x,并且 (v 0, v 1) 是图中的一条边,(v 1, v 2), (v 2, v 3) 等等也是。这样路径的长度是 k。

例如,在上面的无向图,(4, 3, 1, 6) 是一条路径。



这条路径是说包含(contain)了顶点v 0,v 1等等,也包含了边(v 0, v 1),(v 1, v 2)等等。

如果在之间存在一条从 u 到 x 路径 p,则称 x 是从 u 经由 p 可达(reachable)

如果所有被经过的顶点在该顶点序列中只出现了一次,那么我们就称它是简单(simple)路径

(cycle)是指起始和结束顶点是相同顶点的路径。简单(simple)是指,除了起始(结束)顶点外,所有被经过的顶点在该环中只出现了一次。

这些定义同样适用于有向图(例如, (v 0, v 1),(v 1, v 2) 等等必须为弧)。


图的表示

选择图的表示是很重要的,不同的图表示方法有不同的时间和空间开销。

顶点一般用编号来表示它们,所以我们可以用顶点编号来索引它们。因而,现在的问题重点集中在如何存储边上了。

* 边集(Edge List)

表示边最显而易见的方法是,存储一张包含所有边的表,用顶点对表示图中的每条边。

这种表示方式容易编码,也容易来调试,更相当节省空间。但是,确定给定边是否存在所需要的代价是昂贵的,即确定2个顶点是否相连。添加一条边是很快速的,但是如果边在表的位置是未知的,并尝试删除它,就会使问题变得很棘手。

对于带权图,边集表示法需要在每条边中添加一个元素,即边权。扩展这个数据结构来处理有向图很简单。表示稠密图也是微不足道的。

例:略。

* 邻接矩阵(Adjacency Matrix)

第二种方法来表示图是利用了邻接矩阵。这是一个 N*N (N为顶点数)的二维数组。如果图中存在边 (i,j),[i,j] 的值就是1,否则为0。对于一个无向图,这个矩阵是对称的。

这种表示方法也很容易编码,但对空间的需求和浪费也很大,尤其是对于较大的稀疏图。矩阵变大时,调试起来也很麻烦。寻找与该顶点相连的边所需的代价是昂贵的(linear in the number of vertices),但是判断2个顶点是否相连就很快速,而且添加删除一条边也很快。

对于带权图,[i,j] 是用来存储边权。对于无权复杂图,[i,j] 是用来存储2个顶点之间边的数目。对于有权复杂图,表示它就变得很困难。

例:略。

这个事实有时候是很有帮助的,the (i,j) entry of the adjacency matrix raised to the k-th power gives the number of paths from vertex i to vertex j consisting of exactly k edges.(译者:此处比较费解,故略去。)

* 邻接表(Adjacency List)

第三种表示方法是,存储与该顶点相连边的表。它可以用一个长度为 N (N 为顶点数)的数组来实现。第 i 个数组元素是存储了与该顶点相连的边(边用与该边相连的顶点编号来表示)。

这种表示方法较难编码,特别是2个顶点之间边的数目不受限制的时候,所以表必须为链表(或者动态分配内存)。调试它有点困难,特别是使用了链表的时候。但是,这种表示方法和边集使用的内存一样。在这种结构里,查找与该顶点相连的顶点所需代价是很便宜的。添加一条边是很快速的,但是如果边在表的位置是未知的,并尝试删除它,就会使问题变得很棘手。

对于带权图,可以扩展数据结构,并在每条边上添加一个元素来表示权值。复杂图也是可以表示的。有向图也很容易,只需要单向存储弧,或者标记弧的方向就可以了。

例:略。

选择合适的表示方法

对于一些图,图本身不需要全部存储。例如,对于上面的 Knight moves 和 Overfencing 问题,只需要记录相邻顶点,以及检查邻接,所以不需要存储不相邻顶点的信息。这些信息来自图本身的暗示。

如果按这种方法存储图是可行的,并且可以减少空间与编码复杂度,使编写和调试变得很简单,那么它通常就是正确的。

假设 N 是顶点数,M 是边数,dmax是某顶点最大度数,下面的表总结了几种方法的不同点:

效率

边集

邻接矩阵

邻接表

空间

2*M

N2

2*M

判断是否相邻

M

1

dmax

计算所有相连顶点

M

N

dmax

添加边

1

1

1

删除边

M

2

2*dmax


连通性(Connectedness)

如果无向图的每对顶点都有路径相连,它就被称作连通图。例图不是连通的,因为顶点2和顶点4之间没有路径。



但是如果在顶点5和6之间添加一条边,这个图就变成了连通图。

非连通图的连通分量(component)是指它的极大连通子图,连通分量中的每对顶点都是互相可达的。原图有2个连通分量,{1, 3, 4, 6} 和 {2, 5}。注意 {1, 3, 4} 不是连通分量,因为它不是极大的。

如果有向图的每对顶点都有路径相连,它就被称作强连通(strongly connected)

一个有向图的强连通分量(strongly connected component)是指非强连通图的极大连通子图。


子图(Subgraphs)

如果 V' 是 V 的子集,而且E' 是 E 的子集,那么图 G' = (V', E') 是 G = (V, E) 的子图

在边集 E' 中出现的边必须是连接顶点集 V' 中2个顶点的边。

举例,V' = {1, 3, 4, 2} 是例图的一个子图。



特殊的图

(tree)是指连通的,无环的无向图。


许多树是有根树(rooted),它们有个最高的节点,被称作(root)。在树中,除了根节点的每个节点都只有一个祖先(parent),即上面与它相连的节点。而且每个节点可能有很多子孙(children),即下面与它相连的节点,上图即是一个有根树。

森林(forest)是指非连通的,无环的无向图。


有向无环图(directed acyclic graph)通常被叫做dag。

完全(complete)是指图中的任意顶点对都有边相连的图。



二分(bipartite)是指顶点能被分成2个顶点集 V1 和 V2,并且 V1 和 V2 内部都没有边相连的图。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值