1、大学课件图论的基本思想及方法图论的基本思想及方法湖南省长沙市长郡中学 任恺【摘要】文章着眼于图论基本思想及方法的讨论,不涉及高深的图论算法。文章主要从两方面阐述图论的基本思想:一是合理选择图论模型;二是如何深入挖掘问题本质,充分利用模型的特性。同时还归纳了一些解决问题的普适性方法。【关键字】基本思想、图论模型、问题本质、定义法、分析法、综合法【正文】一、引论图是用点和边来描述事物和事物之间的关系,是对实际问题的一种抽象。之所以用图来解决问题,是因为图能够把纷杂的信息变得有序、直观、清晰。因而图论中最基本的思想就是搭建合适的模型,深刻挖掘问题的本质,分析和利用图论模型各种性质,从而到达解决问题的
2、目的。下面着重从模型的选择和发掘利用图的性质来阐述图的基本思想和运用方法。二、合理选择图论模型在解决一道实际问题时,往往先将实际问题抽象成一个数学模型,然后在模型上寻找合适的解决方法,最后再将解决方法还原到实际问题本身。而图论模型就是一种特殊的数学模型。在搭建图论模型时,是通过图中的点和边来体现原问题的特点。搭建的模型务必要真实的、贴切的和透彻的反映出原问题的本质,同时也要做到力求简练、清晰。图论问题往往关系错综复杂,变化多端,因此搭建一个合适的模型实非易事。在选择图论模型时,应该深入分析实际问题的特点,大胆的猜想和验证。下面通过一个具体实例,来揭示选择合适图论模型的重要性和一些方法:例一:滑
3、雪者(Poland Olympiad of Informatics 2002 Stage III:Skiers)题目大意:给出一个平面图,图中有n(2 n 5000)个点,m条有向边。每个点都有不同的横坐标和纵坐标,有一个最高点vh和一个最低点vl。每条有向边连接着两个不同的点,方向是从较高点连到较低点。对于图中任意一点u,都至少存在一条vh到u的路径和一条u到vl的路径。任务:图中由每个点发出的边都已经按照结束点的位置从左到右给出。要求你用若干条从vh到vl的路径覆盖图中所有的边,并且使路径数最少。所谓覆盖,就是指每条边至少在一条路径中出现。选取的路径之间可以有相同的边。(题目中和下面分析中
4、所说的路径都是有向路径,若a到b存在一条路径,并不表示b到a一定存在一条路径。)原题请见附录样例: 图2-1中所示的平面图最少需要8条路径才能覆盖所有的边。* 以网络流为模型分析一下样例,很快联想到经典的网络流模型:最高点vh 是网络的源点,而最低点vl 是网络的汇点。题目中的路径是网络中从源点到汇点的流。要求用路径覆盖图中所有的边,且路径数最少,就是要求网络中每条边的流量大于等于1,并且从源点流出的总流量最小。因此解决这个问题只需要建立一个有容量下界的网络,然后求这个网络的最小可行流。大致做法:首先求出可行流:枚举每条流量为0的边,设为(i,j)。找到一条从s到i的路径和一条从j到t的路径。
5、对“s i j t”路径上的每一条边流量加1,这样既满足了每个点的流量平衡,又满足了边(i, j)的容量下界。然后在可行流上进行修改,从汇点到源点求一个最大可行反向流,就得到了一个最小可行流。分析算法二的复杂度:求可行流时,可以先预处理源点和汇点到每个顶点的路径,因此构造可行流的时间复杂度为O(|E|+|V|)。求最大流时,可以用朴素的增广路算法,复杂度为O(|E|C),C是进行增广的次数。因为是平面图,根据欧拉公式有O(|E|)=O(|V|),而反向流的流量最大为O(|E|),所以总的复杂度为O(|V|2) = O(n2)。此算法实际效率很高,能够迅速的通过测试数据。但是,这种模型并没有很好
6、的挖掘原题中平面图的性质,所以改进的余地应该很大。* 以偏序集为模型题目中强调了每个点都有不同的横纵坐标,图是有向无环平面图。而且图中两点之间的有向边似乎反映着一种元素的比较关系。是否存在更好的模型描述此图呢?为了更好的揭示问题的本质,下面引入偏序集。* 偏序集的相关概念偏序集是一个集合X和一个二元关系R,符合下列特性:a)对于X中的所有的x,有x R x,即R是自反的。b)对于X中的所有的x和y,只要有x R y且x y,就有,即R是反对称的。c)只要有x R y和y R z,就有x R z,即R是传递的。符合这些特性的关系叫做偏序,通常用标记R。a b也可以记作b a。若有a b,且a b
7、,那么就记作a a。又叫做严格偏序关系。含偏序的偏序集X用(X, )表示。令R是集合X上的一个偏序,对于属于X的两个元素x、y,若有x R y 或y R x,则x和y被称作是可比的,否则被称为不可比的。集合X上的一个偏序关系R,如果使得X中的任意一对元素都是可比的,那么该偏序R就是一个全序。例如,正整数集上的小于等于关系就是一个全序。令a和b是偏序集(X, )中的两个元素。若有a b,且X中不存在另一个元素c,使得a c b,那么就称a被b覆盖(或b覆盖a),记作a c b。若X是一个有限集,由偏序集的传递性易知,任一个偏序关系都可以用多个覆盖关系表示出来,也就是说可以用覆盖关系有效的表示偏序
8、关系。有限偏序集(X, )的图表示(也就是哈斯图)是用平面上的点描述的。偏序集中的元素用平面上的点来表示。若有a b,那么a在平面上的位置(严格说是坐标平面中的纵坐标)就应当低于b在平面上的位置。若a c b,那么a和b之间连一条边。也可以用有向图来表示偏序关系,图中的每个结点对应偏序集中的每个元素。若偏序集中的两个元素有a c b,那么对应到图中的两个结点a和b,就有一条从b到a的有向边(b, a)。因此可以看出原图事实上是一个偏序集的图表示。链:链是E的一个子集C,在偏序关系下,它的每一对元素都是可比的,即C是E的一个全序子集。反链(或称杂置):顾名思义,它和链的定义恰恰相反。反链是E的一
9、个子集A,在偏序关系下,它的每一对元素都是不可比的。链和反链的大小是指集合中元素的个数。* 构筑原问题的偏序集模型有了上文有关偏序集的概念,不难搭建出原问题的偏序集模型:令原图表示的偏序集为(X, ),而新构造的偏序集为(E, )。则集合E满足,即E中的元素全部是图中的有向边。令a、b为E中的两个元素,设。当且仅当时,有a b,即存在一条从有向边a到有向边b的路径。当且仅当va = ub时,有a c b。原问题可以重新用偏序集语言表述为:将偏序集(E, )划分成最少的链,使得这些链的并集包含所有E中的元素。直接计算链的个数似乎并不容易,好在有Dilworth定理揭示了链与反链的关系,从而使得问
10、题的目标进一步转化。定理2.1 : Dilworth定理 令(E, )是一个有限偏序集,并令m是E中最大反链的大小,M是将E划分成最少的链的个数。在E中,有m = M。证明过程请参见附录。根据Dilworth定理,问题转化成求E中最长的反链的大小。也就是要求在原图中选尽量多的边,同时保证选出的边是互不可达的(即在(E, )中不可比)。如何求解最长的反链呢?事实上,这和原题给出的平面图有很大关系,接下来,返回到原图上继续讨论。* 从偏序集模型回归到原题由于原题给出的图是平面图,而且图中顶点也是从左到右给出的,那么对于反链中的所有边都能按照从左到右的顺序排列好。如果用一条线将最长反链所对应的边从左
11、到右连起来(如图2-2所示),那么这条线不会与平面图中的其它边相交。更加准确地说: 定理2.2:将最长反链所对应的边从左到右排列好,相邻的两条边一定是在同一个域(闭曲面)中。所谓的域,是由从一个点到另一个点(一个是极高点,一个是极低点)的两条不同路径(两条路径没有公共边)围成的一个曲面,在这个曲面里没有其他的点和边(如图2-3所示),记作F。在围成域F的两条路径中,左边的那条路径定义为F的左边界,右边的那条路径定义为F的右边界。关于定理2.2的简略证明请参见附录。受定理2.2的启发,我们可以用递推的方法求得图中最长反链的长度。设f(x)表示在边x左边的平面区域中以x结尾的最长反链的长度。设x在
12、某个域F的右边界上,有。因为根据定理2.2,若x在某个最长反链中,那么反链中和x相邻且在x左边的边,只有可能在域F的左边界上。得到这个递推式后,只需要按照从左到右从上到下把每一个域求出进行递推即可。* 相应的算法设计可以用DFS深度优先遍历实现平面图中域的寻找。DFS中需要记录两个信息:结点的颜色和扩展它的父结点。每个结点的颜色用Cu来记录。Cu有三种状态:白色表示结点u尚未被遍历,一开始所有结点的颜色都是白色;灰色表示结点u已经被遍历,但是它尚未检查完毕,也就是说它还有后继结点没有扩展;黑色表示结点u不但被遍历且被检查完毕。扩展它的父结点用pre记录。算法的大致框架如下:DFS(结点u)be
13、ginCu 灰色while v是u后继结点 do (按照从左到右的顺序扩展u的后继结点v)if Cv 是白色then beginprev u DFS(v)end else begin vl vvh vwhile Cvh 是黑色 do vh prevh (是黑色,说明是域的边界上的结点;灰色就是极高点) 递推求出右边界的f(x) (pre回溯的边是左边界,是右边界)prev u endCu 黑色end计算上述算法的复杂度:a.对每一个点进行DFS遍历,复杂度为O(|E|);b.回溯寻找每个域边界上的边,并且进行递推求解。由于是平面图,每条边最多属于两个不同域的边界,因此这一步的复杂度为O(|E|
14、+|F|)。因为原题给出的图是平面图,根据欧拉定理,边数|E|和域数(或者说面数)|F|都是O(n)级别的。因此总的时间复杂度为O(n)。* 小结方法一利用网络流模型直接的体现了原题的网络(有向无环)特性,解法具有一般性,但是没有充分的体现出原题的平面图性质。而方法二很好的利用偏序集模型实现了问题目标的转变,从原来的网络流问题回归到问题本身的平面图上,完整的揭示了问题的本质。正是由于回归到问题的本质,后面才能用DFS充分挖掘平面图的性质,得到最优复杂度的算法。从上述两种方法的比较可以看出,两种不同的图论模型导致了两种算法在时间复杂度上的较大差异,可见选择模型的重要性。正所谓“磨刀不误砍柴功”,
15、在设计算法之前,选择一个正确的图论模型往往能够起到事半功倍的效果,不仅能降低算法设计的难度,还使设计出的算法简单高效。在为实际问题选择合适的图论模型的时候,不能仅仅局限于问题表面所表现的某些性质,只根据自有的经验去解题,否则会落入俗套,得不到效率最高的算法。新题新作,应该创新思路,深入分析问题的各种性质,将这些性质结合在一起,从而寻找到最能体现问题本质的图论模型。很多时候,最终算法并不是基于所选图论模型来设计的,就如方法二,偏序集并没有出现在DFS中,但一旦想到偏序集,问题可以说就解决了一半。图论模型更多的是思考的一种过渡,使思路变得清晰,就像一座灯塔,指引你到成功的彼岸。三、充分挖掘和利用模
16、型的性质上一节讲述了选择合适模型的重要性和搭建图论模型的方法。建立模型仿佛是为算法设计搭建一个平台,接下来的工作是在这个平台上充分挖掘和利用原题的性质,设计一个解决问题的好算法。如何挖掘和利用模型的性质呢?下面同样用一个具体实例来说明。例二:爱丽丝和鲍勃(ACM Central European Programming Contest 2001 Problem A : Alice and Bob)题目描述:爱丽丝和鲍勃在玩一个游戏。爱丽丝画了一个有n(n 10000)个顶点的凸多边形,多边形上的顶点从1到n按任意顺序标号。然后她在多边形中画了几个不相交的对角线(公共点为顶点不算相交)。她把每条
17、边和对角线的端点标号告诉了鲍勃,但没有告诉他哪条是边,哪条是对角线。鲍比必须猜出顶点顺(逆)时针的标号序列,任意一个符合条件的序列即可。原题请见附录例如:n = 5,给出的边或对角线是(1,4),(4,2),(1,2),(5,1),(2,5),(5,3),(1,3)。那么一个可能的顶点标号顺序为(1, 3, 5, 2, 4)。对应的多边形如图3-1:* 建立模型根据题目意思,不难得到它的图论模型:凸多边形对应了一个有n个顶点的图G,多边形的边和对角线对应着图G中的边。而且十分明显的是,图G是一个平面图,根据欧拉公式,图中边的数量级为O(n)。研究图G的平面图性质可以发现结论3.1:一条对角线将
18、凸多边形分成了两部分,每部分都至少含有一个除对角线外顶点,而且这两部分分居在对角线的两侧。由此可知,在图G中只存在惟一的一条哈密顿回路。因为对角线会将多边形分成不相关连的两部分,所以对角线不可能存于哈密顿回路上。因此哈密顿回路上的边都是由多边形上的边组成,而多边形的边只有n条,可知哈密顿回路也就只有一条。不妨设这条哈密顿回路为H1,H2,H3Hn。问题的目标就是要找到这个哈密顿回路。下面讨论如何利用这些性质来设计算法。* 利用边的连通性由结论3.1可知,如果一条边是对角线,那么将对角线的两个端点从图G中删除,图G一定会变成两个互不可达的连通分块;而如果一条边是多边形上的边,那么将这条边的两个端
19、点删除,图G将仍然是连通的。也就是说能够根据图G中边的连通性,来判断一条边是对角线还是边。因此,得到算法一:算法一:1枚举图中的每条边(u, v),进行如下判断:将u和v两个顶点从图G中删除得到新图G。在新图G任选一点a,然后从a开始对图G进行遍历。如果a能够到达图G中的其它点,那么就说明图G是连通的,(u, v)是多边形的边;否则,图G不连通,(u, v)是多边形的对角线。2将图G中所有对角线删除,得到新图C。这时的新图C便是图G中的哈密顿回路,因此只要对其进行一次遍历就可以得到多边形顶点的标号序列了。分析一下算法一的复杂度:步骤1中,要枚举的边最多为2n条,每判断一次图的连通性为O(n),
20、所以复杂度为O(n2);步骤2中,删除边和遍历新图的复杂度都为O(n)。所以总的复杂度为O(n2)。n最大时候达到10000,因此算法一的复杂度稍稍高了一点,仍要继续优化。* 分而治之继续挖掘图G的性质发现,由于图G中的对角线是不相交的,那么必定存在一个顶点u,它的度数为2。而且可以肯定的是,和u相连的两条边一定是多边形的边。将以u为顶点的三角形从多边形上删除,剩下的图形仍然是一个多边形。是否能用这个性质判断一条边是多边形的边还是对角线呢?答案是肯定的。由于图中一定存在一个顶点u,它的度数为2。设u是哈密顿回路上的顶点Hi,其相邻的两个顶点为Hi-1和Hi+1。而(Hi-1, Hi)和(Hi,
21、 Hi+1)两条边都是多边形的边,将这两条边添加到一个附加图C中(附加图C一开始只有n个顶点,对应着多边形的顶点,顶点之间没有边相连)。将以u为顶点的三角形(即三角形HiHi-1Hi+1)从多边形上砍掉之后,剩下的图形仍然是一个多边形。也就是说,可以把Hi从图G中删除,若Hi-1 和Hi+1之间没有边相连,就添加一条新边(Hi-1,Hi+1)(虚边),得到新图G。这时,新图G中仍唯一存在一条哈密顿回路Hi-2 ,Hi-1, Hi+1, Hi+2。图G和图G具有同样的性质,因此也至少存在一个度为2的点,令其为Hj。那么(Hj-1, Hj)和(Hj, Hj+1)这两条边有可能为多边形的边、多边形的
22、对角线或者新添加的虚边,将其中多边形的边添加到图C中。然后按照同样的方法把Hj从图G删除,得到一个新图。以此类推,不断地从新图中找到度为2的点,然后将其相应的两条边中是多边形的边添加入图C中,接着从图中删除这个点。如此反复,直到图中不存在度为2的点。然后把图中剩下的边中,是多边形的边的添加到图C中。最后,图C便是要求的原始多边形。样例的模拟过程如下:还存在一个问题没有解决:如何判断移除的边是否是原多边形的边呢?首先考虑一下,一条边(Hi, Hj)什么时候才会被移除。一条边(Hi, Hj)当且仅当成为某个多边形的边时,它才有可能被移除。如果(Hi, Hj)是原始多边形的一条对角线,当且仅当哈密顿
23、回路上从Hi+1到Hj-1的顶点都已经被删除,(Hi, Hj)才有可能成为新多边形的边。如何判断从Hi+1到Hj-1的顶点是否已经被删除呢?这时构造的附加图C就起到了作用!若从Hi+1到Hj-1的顶点已经被删除,则这些顶点在原多边形上相应的边都已经添加到图C中,Hi到Hj在图C中一定存在一条路径。因此判断一条移除的边(Hi, Hj)是否是对角线,只需要判断在图C中Hi和Hj是否连通。值得注意的是,当图C中已经有了n -1条边时,剩下的那条边会被判断成对角线,但此时已经能够确定多边形顶点的标号序列了。算法的大致轮廓已经清楚了,下面为算法选择合适的数据结构:a.图G的存储结构:由于图G是稀疏图,可
24、以用邻接表存储,用来查找度为2的顶点与哪些边相连。还要用一个哈希表存下所有的边,用于查找任意两个点是否相连。设一条边为(u, v),哈希表可以用作为关键字,哈希函数为,P为大质数。这样在保证查找复杂度仍然是O(1)的情况下,存储空间比邻接矩阵小了很多。b.枚举度为2的结点:很容易想到用最小堆来找出度为2的顶点,不过这样的复杂度稍稍高了一点。由于顶点的度数只减少不增加,而且真正有效的度数只有1和2,所以可以建立四个桶来替代堆。将顶点按度数分别放到四个不同的桶中:度数为0、度数为1、度数为2、度数大于2。在每个桶中用双向链接表存储下不同的结点。当一个顶点的度数被修改的时候,从原桶中删除,放到相应的
25、桶中。在双向链表中的插入和删除结点,时间复杂度都是O(1)。而因为每个结点的度数是不断减少的,所以每个结点最多进出每个桶一次。综上所述,在这些桶中查找和调整一个度为2的结点所需的时间复杂度为O(1)。c.在图C中添加边,判断任意两点的连通性:可以采用并查集来实现边的添加(即将两个连通子图合并)和判断点的连通性(即判断两个点是否在同一个连通子图中)。添加一条边和判断一对点的连通性两种操作的均摊复杂度为O(n)。下面是对算法二的总括:算法二1根据每个顶点的度数将n个顶点放到四个桶中。初始化附加图C。2如果存在一个度数为2的顶点u,则接下来执行第3步,否则转步骤6。3在邻接表中找到和u相连的两个顶点
26、为v1和v2。4首先判断(u,v1)、(u,v2)是否为虚边。若不是虚边,用并查集检查其是否为对角线。最后将是多边形的边插入到图C中。5将顶点u标记为不可用。用哈希表检查边(v1,v2)是否存在图G中。如果边(v1,v2)不存在,则添加一条虚边(v1,v2),v1和v2的度数不变;否则将v1和v2的度数减一。若v1或v2修改后的度数不符合所在桶的性质,则进行调整。然后转到步骤2。6找到残图G中所有度数为1的顶点,一一检查这些顶点相应的边在附加图C中的连通性,把非对角线和虚边的边插入到图C中。7遍历图C得到原始多边形顶点的标号顺序。在每个顶点删除时,最多添加一条虚边,因此原始边和虚边的总数仍然是
27、O(n)的级别。现在分析一下时间复杂度:步骤3中,每个顶点最多查找一次,因此复杂度为边数,即O(n);步骤4和步骤6中,用并查集查找和插入的均摊时间复杂度为O(n(n);步骤5中,用哈希表查找一条边的复杂度为O(1),边的插入和桶的调整也是O(1),一共进行顶点数次,所以时间复杂度为O(n)。综上所述,算法二的复杂度为O(n(n)。算法二的时间复杂度已经十分低了。但追求无止境的我们不能浅尝辄止,因为算法二仍存在需待改进的地方:编程复杂度实在太高了!算法二虽然已经较为充分的挖掘出问题的各种特性,但在利用这些特性时,是通过不断分解成子问题然后一一击破的方法来实现的。我们不禁提出一个问题:是否能找到
28、一种综合的方法,将所有特性一起利用,使得解决方法既简便又高效呢?* DFS树反映的问题特性回到多边形所在的平面图上。若按深度优先来遍历平面图,当经过一条对角线时,平面图便被分成了两个部分。由于是深度优先遍历,那么在这两部分剩下的点中,有一部分的点会被优先遍历到。因此可以模仿DFS寻找块的算法,利用顶点的遍历顺序和low函数来判断边的性质。首先定义一下DFS中需要用到的两个函数:dfnv表示v是深搜中第几个被遍历到的。 其中w1表示v的儿子结点,w2表示DFS树中异于v的父亲结点的其他祖先结点。接下来分情况讨论如何用dfn和low函数判断一条边的性质:考虑DFS树上的一条边(u, v),其中u是
29、v的父亲结点。由于图G是一个块,因此每个点的儿子个数不会超过2。根据v的度数分下面四种情况:1v的儿子数为0:意味着(u,v)是原始多边形的边。否则的话,v所有的祖先结点都在(u,v)的一侧,而另一侧一定仍有点存在,与儿子数为0矛盾。令x是与v直接相连的祖先结点中dfn值最小的一个结点,那么(x,v)一定也是原始多边形的边。略证:如图3-3,另(x,v)为多边形的边。v不是x的父亲结点,说明x一定先于u被遍历到,而且x是u的祖先结点。也就是说,x到u存在一条路径,路径上的边都是由DFS树上的边组成。令y为异于x和u,而与v相连的点。由于图G是平面图,那么y一定在x到u路径上。因此y一定后于x被
30、遍历,即dfny小于dfnx。所以x一定是与v相连的祖先结点中dfn值最小的。2v的儿子数为1,且u为DFS树的根:易知,(u, v)一定是多边形的边。3v的儿子数为1,且u不是DFS树的根:令w为v惟一的儿子。若loww大于等于dfnu,则(u, v)为多边形的对角线。因为(u, v)将平面分成了两部分,w和其子树结点是遍历不到另一部分的,如图3-4。令x是与v直接相连的祖先结点中dfn值最小的一个结点,那么(x, v)一定是原始多边形的边(证明同情况1中的分析)。而与v相连的另一条多边形的边可以在遍历w时找到。若loww小于dfnu,则(u, v)是多边形的边,而与v相连的另一条多边形的边
31、可以在遍历w时找到。4v的儿子数为2,则与v相连的两条多边形的边可以在遍历儿子结点时找到。考虑上述四种情况已经能够判断图G中所有边的性质了。因此只需要对图G进行一次深度优先遍历,就能确定多边形顶点的标号顺序。所以算法三的时间复杂度为线性的O(n)!* 小结上述三种方法都是建立在同一个模型上的,不同的方法对模型性质挖掘的深度不同也就决定了不同的时间复杂度。算法一运用了定义法,利用对角线将多边形划分成两部分的性质找到多边形中所有的对角线。而在算法二的设计过程中,发现了每次删除多边形的一个角时仍是一个多边形,也就是找到了子问题的相似性,这样就可以不断地缩小问题的规模。算法二还体现了一种化归的思想,将未知问题分成几个步骤(或者子问题),每个步骤都是我们熟知的,因此可以为每一步选择最好的算法。由于每个子问题都解决了,原问题也就迎刃而解。可以说方法二是一种分析法。算法三体现了一种综合思想,不是单独考虑每一条边的连通性,而是从全局考虑,发现了多边形的边和对角线在DFS树中的区别。因此算法三的设计一气呵成,体现了图论中一种“序”的优美性。三种不同的方法也给了我们不同的启示:定义法告诉我们,当找不到问题思考的方向时,可以考虑从问题最基本的性质入手寻找突破口。分析法的好处是,分解后的子问题一般比原问题要简单,困难的是每一
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1