图论专题总结

ACM课程的最后一个专题,图论,其实这个专题还是比较有意思的,不过因为最后课时紧张,讲的也不是很详细。对于图也只是学个皮毛,因为快到期末考试了,题目做的也不是很多,其实还是学的东西不深,后面题目一难就不会做了。

一般图的问题都是根据路径求最小的问题,例如最短路程,最小花费等等。首先是并查集的问题,简单来说就是合并两个不相交的集合,这类题目有两个步骤。查找与合并,查找查的就是属于哪个集合,之后合并。因此做这类题目的时候需要两个函数分别实现查找和合并的功能。例如Problem C,把路连接起来的畅通工程的题就是典型的并查集。

之后是最小生成树的问题,这个问题主要是解决路径带权值的问题。求最小生成树主要有两个算法,prim算法与kruskal算法。对于Prim算法就是任取一个顶点加入生成树;在那些一个端点在生成树里,另一个端点不在生成树里的边中,取权最小的边,将它和另一个端点加进生成树。重复上一步骤,直到所有的顶点都进入了生成树为止。一般prim算法用邻接矩阵存储图,虽然Prim算法很难理解也比较复杂,不过代码重用性很高,只要把图建好,用同一个Prim算法大都能解决。本次专题的Problem A B C D E等都可以用同一个Prim函数解决,唯一有所变动的就是主函数建图的过程以及一些数据类型的变换。对于Kruskal算法思想就是对所有边从小到大排序,依次试探将边和它的端点加入生成树,如果加入此边后不产生圈,则将边和它的端点加入生成树,否则,将它删去。直到生成树中有了n-1条边,即告终止。也就是有点贪心的意思,一般用链表的形式来存储图的数据。

最后一节课讲的内容有点多,吸收不了。一口气讲了4个算法。分别是Bellman-ford算法。spfa算法,dijkstra算法,floyd-washall算法,这几个算法都是为了解决类似,给出两个点求出最短路径的问题。常用的就是dijkstra算法,主要思想设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,对viV-S,假设从源点vvi的有向边为最短路径。以后每求得一条最短路径v,…, vk,就将vk加入集合S中,并将路径v,…, vk, vi与原来的假设相比较,取路径长度较小者为最短路径。重复上述过程,直到集合V中全部顶点加入到集合S中。但是他有自身的局限性,就是不能处理负权值。对于负权值的问题用bellman算法,来弥补。spfa算法就是更加优化了bellman算法。总的来说就是

Dijkstra 算法的效率高,但是也有局限性,就是对于含负权的图无能为力。
Bellman-Ford
算法对于所有最短路长存在的图都适用,但是效率常常不尽人意。
SPFA
算法可以说是综合了上述两者的优点。它的效率同样很不错,而且对于最短路长存在的图都适用,无论是否存在负权。它的编程复杂度也很低,是性价比极高的算法。

最后也是最简单的floyd算法,就是用的三重循环看经过某一个节点是不是与不经过他更短。例如Problem I M N。都是用这种算法写的。应为比较简单,理解起来,写起来都很简单。

你可能感兴趣的:(图论专题总结)