二分图(Bipartite Graph)
若能将无向图G=的顶点集V划分成两个不相交的非空子集V1和V2,使得G中任何一条边的两个端点一个属于V1,另一个属于V2,则称G为二部图(二分图,也称为偶图)。
V1和V2称为互补顶点子集,G记成G=<V1, V2, E>。
二分图检测算法(染色+DFS)
V1和V2两个顶点子集中的顶点分别用不同的颜色表示。
假设V1中的顶点为蓝色,V2中的顶点为绿色;
结合二部图的性质可得:任何一个顶点与其相邻结点一定不同色。
故基于DFS对所有顶点进行染色,并检测顶点与其相邻顶点的颜色是否不同来判断该图是不是二部图。
同构图
假设G=(V,E)和G1=(V1,E1)是两个图,如果存在一个双射m:V→V1,使得对所有的x,y∈V均有xy∈E等价于m(x)m(y)∈E1,则称G和G1是同构的。
平面图
没有交叉边的图
BFS(广度优先遍历)
在无向图中使用BFS求单源路径问题,得到的一定是单源最短路径。(得到的永远都是最少边数的路径)
原因:BFS遍历的本质实际上是构造一棵以该节点为根,高度最矮的优先搜索树,高度最矮,因此距离最短。
非递归形式图遍历
BFS:栈(stack)
扫描二维码关注公众号,回复: 13248484 查看本文章DFS:队列(queue)
X表示任何一个容器;
X是栈,则BFS;
X是队列,则DFS;
X是随机队列,可用于迷宫生成。
图论建模(应用:FloodFill算法)
1、构建模型
2、状态表达(包含:状态压缩)
桥
对于无向图,如果删除了一条边,整个图联通分量数量变化,则这条边称为桥(Bridge)。
找桥算法(DFS)
判断v-w是否是桥,看通过w,能否从另一条路回到v或者v之前的顶点。
- 对于每一个顶点,记录DFS的顺序;ord[v]表示顶点v在DFS的访问顺序;
- 对于每一个顶点,记录能到达的最小ord,low[v]表示DFS过程中,顶点v能达到的最小ord值。
- 桥就是一条两边顶点所对应的low值不同的边
BFS遍历树和DFS遍历树
寻找桥的算法不能使用BFS完成
割点
对于无向图,如果删除了一个顶点(顶点领边也删除),整个图联通分量数量变化,则这个顶点称为割点(Cut Points/Articulation Points)。
在算法中,如果点v有一个(BFS遍历树中)孩子节点w满足low[w]>=ord[v],则v是割点+特殊情况:对于根节点,如果有一个以上的(BFS遍历树中)孩子,则根节点是割点。
哈密(哈密尔)顿图
经过图中每个顶点一次且仅一次的回路(通路)称为哈密顿回路。(从一个点出发,沿着边行走,经过每个顶点恰好一次,之后回到出发点,经过每个顶点恰好一次)
数学上:找不到充分必要条件(有充分条件,有必要条件,但没有充要条件)
旅行推销员(Traveling Salesman Problem,TSP)
给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短路径。
- 带权图,完全图
- NP难问题
哈密尔顿回路
起点很重要,不是所有点做起始点都有哈密尔顿回路。
状态压缩
1、二维坐标用一个数字表示;
2、两个有限变量用一个值表示。
(将多个可变状态压缩成一个变量进行存储,二进制存储最省空间并使用位运算进行复原)
记忆化搜索
记忆化搜索(通过特定的状态储存,进行剪枝操作)有时不一定好用,可能会极其浪费空间。
注意
P问题
P问题是具有多项式算法的判定问题。这里的P代表Polynomial。P问题就是可以有一个确定型图灵机在多项式时间内解决的问题。即那些存在O(n),O(nk),O(nlogn)等多项式时间复杂度解法的问题。比如排序问题、最小生成树、单源最短路径。直观的讲,我们将P问题视为可以较快解决的问题。
(多项式算法(polynomial algorithm)亦称有效算法或好算法,是一类计算时间不超过始数据量的一个多项式的算法。
算法满足以下的条件:存在多项式P,使算法的时间复杂性函数f(n)=O(P(n)),这里n为问题的输入规模,换言之,有常量C及多项式P,使|f(n)|≤C|P(n)|。
特点:
1.刻画了算法的内在性质,时间复杂度可以用多项式表达,不会因为面对的具体问题不同,而影响对算法这种性质的刻画。
2.渐近性特点,也就是说,当输入规模n增大时,多项式算法的计算时间要比时间复杂性函数为指数函数情形少得多。
3.在实际上,多项式算法并不肯定奏效,如P(n)=n1000,当1时,n1000>2n,其中,t=1000logn,其中log为以2为底的对数。)
NP问题(非确定性多项式难题)
NP(Nondeterministic Polynomially,非确定性多项式)类问题是指一个复杂问题不能确定是否在多项式时间内找到答案,但是可以在多项式时间内验证答案是否正确。NP类问题数量很大,如完全子图问题、图着色问题、旅行商(TSP)问题等。在P和NP问题中,P的难度最低,NP由于只对验证答案的时间作了限定,从而有可能包含某些无法在多项式时间内找到答案的问题,即NP是比P更困难的问题。
NP完全问题
NP完全问题(NP-C问题, Non-deterministic Polynomial Complete,即多项式复杂程度的非确定性问题。简单的写法是 NP=P?,问题就在这个问号上,到底是NP等于P,还是NP不等于P),是世界七大数学难题之一。
NPC问题:NP中的某些问题的复杂性与整个类的复杂性相关联.这些问题中任何一个如果存在多项式时间的算法,那么所有NP问题都是多项式时间可解的.这些问题被称为NP-完全问题(NPC问题)。
NP难问题(NP-hard problem)
需要超多项式时间才能求解的问题。
求解哈密尔顿回路(只能暴力求解,遍历所有路径,O(n!))
欧拉回路(Eulerian Path)
从一个点出发,沿着边行走,经过每个边恰好一次,之后再回到出发点。(经过图(无向图或有向图)中每条边一次且仅一次并且行遍图中每个顶点的回路(通路),称为欧拉回路(欧拉通路),存在欧拉回路的图,称为欧拉图)
- 无向图G有欧拉回路,当且仅当G是连通图且无奇度顶点。
- 无向图G有欧拉通路、但无欧拉回路,当且仅当G是连通图且恰好有两个奇度顶点。
- 有向图D有欧拉回路,当且仅当D是连通的且每个顶点的入度等于出度。
- 有向图D有欧拉通路、但无欧拉回路,当且仅当D是连通的,且除了两个顶点外,其余顶点的入度均等于出度。(这两个特殊的顶点中,一个顶点(终点)的入度比出度大1,另一个顶点(始点)的入度比出度小1)
欧拉回路是数学家欧拉在研究著名的德国哥尼斯堡(Koenigsberg)七桥问题时发现的。如图1所示,流经哥尼斯堡的普雷格尔河中有两个岛,两个岛与两岸共4处陆地通过7座杨 彼此相联。7桥问题就是如何能从任一处陆地出发,经过且经过每个桥一次后回到原出发点。
寻找欧拉回路的三种算法
回溯法(通过深度优先遍历对边进行删除和回溯,直到所有边均被删除)
Fleury算法(一种贪心算法)
- 回溯法+不走桥的边(桥的判断是不能预处理的) O((V+E)²)
- Fleury算法的优化——Hierholzer算法:O(V+E),找环——删边——找唯一存在仅有一个的多环的公共点
Hierholzer算法(可递归可非递归)
有欧拉回路存在的性质可以得出:
在无向图中,从任一点出发,先随便找一个环。如果这个环就是原图,已经找到了欧拉回路。否则,剩下的边一定和我们找到的环相连,且所有顶点的度数依然是偶数,即依然存在环,两个相连的环,一定组成一个新环。
从一个可能的起点出发,进行深度优先搜索,但是每次沿着辅助边从某个顶点移动到另外一个顶点的时候,都需要删除这个辅助边。如果没有可移动的路径,则将所在结点加入到栈中,并返回。
//递归版 void dfs(Node node, Deque trace){ while(!node.edges.isEmpty()){ Node next = node.edges.removeLast(); dfs(next, trace); } trace.addLast(node); }
//非递归版 List dfs(Node node, Deque trace, Stack stack){ stack.push(node); while(!stack.empty()){ if(node.degree() != 0){ stack.push(node); node = node.edges.removeLast(); }else{ trace.addLast(node); node = stack.pop(); } return trace; }
最后得到的栈中保存的就是整个欧拉迹中的顶点。
性质1. 如果图中包含闭欧拉迹,则栈的底部存储的必定是起点。如果图中包含的是开欧拉轨迹,则栈底部存储的是与起点不同的另外一个奇度数端点。
性质2.如果图中包含闭欧拉迹,入栈的倒数第二个顶点一定是路径中的第二个顶点。