推荐书籍《数据结构与算法分析--C++语言描述》p.304-p.316 源代码
1.图论基本知识点
图:图有顶点和边构成。图用符号G表示,顶点用符号V表示,边(或称弧)用符号E表示。G(V,E)表示由顶点集合V和边集合E构成的图。其中边由两个顶点构成,若两个顶点构成的边无序,如v-w和w-v相同,则称无向图,否则称有向图。若(v,w)构成一条边,则称w邻接到v;若是无向图,则w邻接到v且v邻接到w。图有时还有第三种属性,称权(或值)。
路径:图中的路径是顶点序列,路径程度为序列包含的边的数目。如N个顶点组成的路径,长为N-1。从v到v的路径长为0
简单路径:由互异的顶点组成的路径,但第一个和最后一个顶点可能相同。 顶点v到v的路径,称为环。
有向图中的圈:满足长度至少为1,起点与终点为同一个顶点的简单路径。u-v-u是圈。
无向图中的圈:满足有向图圈的要求,且边是互异的。因此u-v-u不是圈。
无向图的连通性:对于无向图,若每个顶点到其他顶点都存在路径,则称无向图连通。
有向图的连通性:对于有向图,若每个顶点到其他顶点都存在路径,则称有向图强连通。若有向图不是强连通,但是其对应的无向图(有向图的边去掉方向)是连通的,则称该有向图弱连通。
完全图:每一对顶点都存在一条边的图
图的表示
邻接矩阵:使用一个二维数组,每条边(u,v)对应g[u][v],若边存在,则g[u][v]置为true,否则置为false。如果边有权,则置为权的值。可以用很大或很小的数字表示不存在的边。邻接矩阵法适合稠密的图。
邻接表:对于每个顶点,使用一个表存放其邻接的顶点,如果边有权,也可以在表中附加权的信息,是图的标准表示方法。可以使用vector实现邻接表,或是映射,因为顶点是互异的。
入度:顶点v的入度为边(u,v)的数目,即所有v邻接的顶点u的数目。入边,如边(u,v)为v的入边。
拓扑排序:有向无圈图中顶点的一种排序,若存在边(vi,vj),即j邻接i,那么排序中j在i之后。拓扑排序不唯一。实现:首先找出图中没有入边(即入度为0)的顶点,在排序表中放置该顶点,之后将该顶点和所有的边从图中删除,继续算法。如果没有入度为0的顶点,说明该图有圈。
赋权路径长:假设图有权,每条边(vi,vj)的权重(或开销)为ci,j,则路径长为边对应的权求和。
无权路径长:路径上所有边的数目,若顶点数目N,则path_min=N-1。
单源 从一个固定起点出发 如s出发到所有的v 或s出发到某一固定的v
2.图论算法
广度优先搜索BFS(BreadthFirstSearch)
按层处理顶点,距开始最近的顶点首先被求值,而最远的点最后被求值,很像树的层序遍历。因为广度优先搜索最先处理相邻的层,因此可用于求最短路径或最小深度。广度优先搜索是盲目搜索,因为算法本身就是从起点开始,先遍历下一层,直到遍历到所有的终点,因此遍历到终点的时间长。
有向图的拓扑排序