目录
记得老师说过学习要有钻研精神,凡事要多问为什么。这里整理了近日做题出现的一些疑问。方便日后回顾。
1,什么是相邻和序偶?
图的路径是:由相邻顶点序偶所形成的序列。
翻译:路径就是由一个个相互邻接节点构成的有序对<x1,x2>,<x2,x3>,…
<
x
n
−
1
,
x
n
>
<x_{n-1},x_{n}>
<xn−1,xn>,组成的序列。
1,相邻
这里相邻我认为应该指两个顶点相互邻接;A与B相邻,暗有A、B邻接之意。
2,序偶:
序:有序
偶:双数;成对的(跟“奇(jī)”相对)(怎么感觉在上语文课)
序偶:一对有序的数.
如: <a,b>是序偶, <b,a>也是序偶,两者是不同的.
如果两个数无序,则称为无序偶.
表示为(a,b);(a,b)和(b,a)是相同的.
2,组合数是什么?在无向图中的应用?
组合数:从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。公式如下:
在无向图中,两个节点之间一定是形成一条无向边。也就是说:V1-V2之间只算一条边。
已知无向图有n个顶点,计算图最多的边数。易知此时每两个节点之间都有一条边。
那么可以利用组合数计算。套用组合数公式:
C
n
2
=
n
(
n
−
1
)
/
2
C_{n}^{2}=n(n-1)/2
Cn2=n(n−1)/2
3,连通n个节点有向图,最少需要n个结点?
v1 v2 … vn
从v1依次指向vn,最后vn指回v1
v1->v2->…vn;vn->v1
4,完全图是什么?
有向图:每两个顶点之间都有两条方向相反的边连接;n(n-1)条边
无向图:每两个顶点之间都有一条边连接;n(n-1)/2条边
5,连通分量与连通子图?
1,连通是什么?
连通图,任意两个顶点之间都连通
强连通图,任意两个顶点之间都有边连接(a->b b->a)
2,讨论范围
首先我们先明确一下,连通图是在无向图中进行讨论的。强连通图是在有向图中进行讨论的
3,连通分量
无向图中极大连通子图(两节点之间有边)就是连通分量;
有向图中极大强连通子图(两个节点之间互相连通)就是强连通分量
注意:
① 任何连通图的连通分量只有一个,即是其自身
② 非连通的无向图有多个连通分量。
③n个节点的无向图最少1个连通分量,最多n个连通分量。
下图是无向非连通图,它有三个连通分量
下图是有向非连通图,它有两个强连通分量
4,连通子图
子图,就是说一个图的边集和点集都是另外一个图的子集。
极大,可以理解为节点极大。
如下图,0-1虽然也是连通子图,但不是极大连通子图。这是因为我们还可以添加2,使0-1-2成为连通子图。而0-1-2是极大连通子图,因为我们无法再扩充一个节点构建连通子图。
极小连通子图:此时如果删除一条边,就无法连通(或者说构成树);如果添加一条边就会有环。
5,强连通子图
极大强连通子图:无法再添加一个节点,构成连通子图
如1-2-3是一个强连通子图,但是不是极大强联通子图,因为还可以添加一个3,使1-2-3-4为强连通子图。而1-2-3-4是极大强连通子图,因为无法再添加其他节点构建强连通子图。
注意:
1,连通图的极大强连通子图为其本身。(是唯一的)
2,非强连通图有多个极大强连通子图。
3,极大强连通子图最多有n(n-1)条边,最少有n条边
不存在极小强连通子图这个概念
6,拓扑排序如何判断有向图有环?
判断有向图有没有环可以利用拓扑排序和深度优先遍历算法。
拓扑排序,寻找一个入度为0的节点删去该节点,所有该节点指向的节点入度减1。如果所有节点被删除则无环。如果有剩余的节点则有环。
如:V1-V2-V3有环,则入度都为1,则拓扑排序到这里就找不到一个入度为0的节点,无法继续下去。
7,BFS计算最短路径为什么不能用于带权且权值不等的图?
与深度优先不同,广度优先遍历是先遍历完最近的节点,逐步向远处节点遍历(通过队列实现,一个节点出队时遍历,然后将其邻近点入队)
BFS计算最短路径时,只能用于单源无权的情况,即,只能计算某一个节点到其他节点的最短距离。
BFS计算最短路径必须权值相等,或者无权值。因为BFS是以边为单位计算距离,认为越邻近的话实际距离也越近。
如果权值不同,可能某一节点距离起始点要进过很多节点,但实际距离却很近。造成了误差。
8,图主要算法的时间复杂度?
前提:假设一个图的节点有V个,边有E条。
1,广度优先遍历
主要时间开销在于访问节点和探索边。
①对于邻接矩阵而言,需要访问v个节点,且对每个顶点都需要访问v次寻找边(遍历矩阵的一行);则时间复杂度为
O
(
∣
V
2
∣
)
O(|V^{2}|)
O(∣V2∣)
②对于邻接表,也需要访问v个节点,但邻接表不会存储没有邻接的情况,因此寻找边的时候只需访问2e次(无向图)。则时间复杂度为
O
(
∣
V
∣
+
∣
E
∣
)
O(|V|+|E|)
O(∣V∣+∣E∣)
2,深度优先遍历
主要时间开销也是访问节点和探索边。
与广度优先遍历类似,只是访问的顺序有些差别。
邻接矩阵为
O
(
V
2
)
O(V^{2})
O(V2),邻接表为
O
(
∣
V
∣
+
∣
E
∣
)
O(|V|+|E|)
O(∣V∣+∣E∣)
3,最小生成树
①Prim(普里姆)算法
从某一顶点开始构建生成树,寻找所有与该节点相邻的边,找到最小的,将其指向的节点纳入树中。下一轮就遍历树中两个节点的相邻边,找最小的。以此类推。
具体代码是利用一个lowcost数组记录各节点加入树的最低成本,lowcost初始化为起始节点到邻接点边的权值;每有一个新节点加入树,就要更新lowcost数组。
则该算法主要时间开销为遍历V个节点,且每次遍历节点都要更新lowcost数组(V次,因为还要判断该节点是不是已经访问过)。其实就是两层嵌套循环,因此该算法的时间复杂度为 O ( ∣ V 2 ∣ ) O(|V^{2}|) O(∣V2∣),主要适合边稠密的图
①Kruskal(克鲁斯卡尔)算法
每次选一条权值最小的边加入树,如果这条边的两个节点已经在树中连通了就跳过,直到树所有节点都连通。
把边按权值递增排序,依次遍历每条边,遍历E轮,判断该边两顶点是否连通(并查集),每次时间复杂度为 O ( l o g ∣ E ∣ ) O(log^{|E|}) O(log∣E∣)。则时间复杂度为: O ( ∣ E ∣ l o g ∣ E ∣ ) O(|E|log^{|E|}) O(∣E∣log∣E∣)。
Kruskal算法主要针对边来展开,边数较少时效率非常高,所以对于稀疏图有很大的优势;
4,最短路径
①Dijstra
使用数组final[]记录是否找到到起始点的最短路径,dist[]记录到起始点的路径长度,path记录路径前驱。
初始化,根据与起始点的邻接关系更新距离,路径等信息,邻接就更新为权值,否则更新为INF。
起始点v0,final[v0]=true;dist[v0]=0;path[v0]=-1;
其余点vi,final[vi]=false;dist[vi]=arcs[v0][vi];path[vi]=if(dist[v0][vi]==INF)?-1:0;
n-1轮遍历,循环遍历final和dist数组,找到为false且距离最短的节点v;final[v]更新为true;检查所有与v相邻的节点,对没有访问且过v的距离小于原始距离的,更新距离和访问情况。
易知,该算法主要有两个部分,首先要进行n-1轮循环,遍历除起始点外的所有节点。每轮循环又要遍历final数组和相邻节点(2n);则时间复杂度为o( n 2 n^{2} n2)。
②Floyd
用矩阵记录,A[]记录任意两点最短路径长度,path[]记录任意两点之间经过的中间节点。
三层循环,从外向内依次是中间点,起点和终点。
依次读取每一个点作为中间点,然后矩阵所有点(i,j),检测经过中间点的路径长度是否小于原始路径长度;如果是就修改A和path。
因此时间复杂度为o( n 3 n^{3} n3)。
5,拓扑排序
扫描所有顶点,入度为0的入栈。
栈不为空就执行循环,把节点依次出栈,将此节点指向的点入度减一;并再将入度为0且没有入过栈的入栈。
所有节点都要入栈(n);对边处理,邻接点入度减一,为0的入栈。因此算法核心还是处理点和边。
①对于邻接矩阵而言,时间复杂度为
O
(
∣
V
2
∣
)
O(|V^{2}|)
O(∣V2∣)
②对于邻接表,时间复杂度为
O
(
∣
V
∣
+
∣
E
∣
)
O(|V|+|E|)
O(∣V∣+∣E∣)
6,关键路径
O(n+e)
9,关键路径唯一吗?
关键路径(不一定唯一,但长度相等):源点到终点的最长路径
关键路径是矩阵中最大路径长度的路径。
求关键路径:
求节点(事件)发生的最早时间(起点为0,后面加上指向该节点路径权值中的最大值)和最迟时间(从终点开始,减去从该点出发的路径权值的最小值)
求路径(活动)发生的最早和最迟时间
求时间余量()
10,对角矩阵是什么?
只有对角线上有非0元素的矩阵称为对角矩阵
11,最小生成树?
一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。
12,关键路径如何加快工期?
1,求关键路径
先求节点的最早和最迟发生时间。最早完成时间就是从起点开始按拓扑排序顺序计算,起始点时间为0,其余时间为上一节点时间+活动持续时间(边权值),有多个的话取最大值;最迟发生时间则是从终点逆推,为当前节点最早完成时间-权值,有多个就取最小值
然后求活动的最早和最迟完成时间,最早发生时间就是活动起始节点的最早发生时间。最迟发生时间是从最后一个活动开始,由活动的指向节点的最迟发生时间-权值(活动持续时间)
最后将活动最迟发生时间-最早发生时间,为0的就是关键路径
2,加快工期的节点
求出一个AOE网的关键路径后,可通过加快关键活动(即缩短它的持续时间)来实现缩短整个工程的工期。但并不是加快任何一个关键活动都可以缩短其整个工程的工期,只有加快那些包括在所有关键路径上的关键活动才能达到这个目的。
除了a之外都是关键路径,则同时加快d和f就可以提前工期。因为在关键路径节点3处的两个分叉,无论走那边都进过了d、f。
如果选f、c,那么e时间不变,节点5的完成时间还是不会改变,工程时间不变。
13,拓扑排序
就是在图中找一个无入度的节点,然后从图中删除,将其指向的节点入度减一。然后再次寻找无入度的节点,依次循环。