图
术语:
1、回路:第一个顶点和最后一个顶点相同的路径。
2、简单路径:序列中不出现重复的顶点。
3、简单回路:除了第一个和最后一个,序列中不出现重复的顶点。
4、连通:两顶点之间存在路径即为连通。
5、连通分量:非连通图的极大连通子图(含有极大顶点数,以及依附于这些顶点的所有的边)
6、在有向图中,强连通与强连通分量。
7、生成树:包含连通图中所有节点的极小连通子图(含n个顶点、n-1条边)。
存储方式主要有两种:邻接矩阵和邻接表。
邻接表的另一种特殊形式:十字链表,包含了有向图的出边表和入边表
图的遍历
有两种方式(需要数组记录顶点是否已经被访问):
1、深度遍历,利用栈实现。
2、广度遍历,利用队列实现。
最小生成树:
在无向连通图中,生成树所有边的权值之和为该生成树的代价。
最小生成树,即为图G所有生成树中代价最小的那棵。
生成最小生成树的算法有两种:
1、Prim算法,基于点集合的选取。
基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树, T的初始状态为U={u0}(u0∈V),TE={ },
重复执行下述操作:在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。
2、Kruskal算法,基于边集合的选取。
基本思想:设无向连通网为G=(V, E),令G的最小生成树为T=(U, TE),其初态为U=V,TE={ },
然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。
若被考察的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为一个连通分量;
若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,
如此下去,当T中的连通分量个数为1时,此连通分量便为G的一棵最小生成树。
最短路径
单源点的最短路径算法:Dijkstra算法,时间复杂度为O(n^2)
基本思想:设置一个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,
对vi∈V-S,假设从源点v到vi的有向边为最短路径。
以后每求得一条最短路径v, …, vk,就将vk加入集合S中,并将路径v, …, vk , vi与原来的假设相比较,取路径长度较小者为最短路径。
重复上述过程,直到集合V中全部顶点加入到集合S中。
任意顶点的最短路径算法:Floyd算法,时间复杂度O(n^3)
有向无环图
AOV网:顶点表示活动图(activity on vertex)
1.AOV网中的弧表示活动之间存在的某种制约关系。
2.AOV网中不能出现回路 。
AOV网应用,拓扑排序:
拓扑序列:设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1, v2, …, vn称为一个拓扑序列,
当且仅当满足下列条件:若从顶点vi到vj有一条路径,则在顶点序列中顶点vi必在顶点vj之前。
拓扑排序:对一个有向图构造拓扑序列的过程称为拓扑排序 。可以通过该方法检测图中是否含有环,即拓扑排序遍历的顶点数小于总的顶点数。
利用栈来实现,1、将当前所有入度为0的点入栈,
2、然后出栈,打印该顶点,并且与该顶点相连所有的边去除。
3、重复第一步。直到栈为空,
AOE网:边表示活动(activity on edge)
在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,边上的权值表示活动的持续时间,称这样的有向图叫做边表示活动的网,简称AOE网。
AOE网中没有入边的顶点称为始点(或源点),没有出边的顶点称为终点(或汇点)。
性质:
⑴ 只有在某顶点所代表的事件发生后,从该顶点出发的各活动才能开始;
⑵ 只有在进入某顶点的各活动都结束,该顶点所代表的事件才能发生。
最短工期:应该是最长路径。
关键路径:
在AOE网中,从始点到终点具有最大路径长度(该路径上的各个活动所持续的时间之和)的路径称为关键路径。
关键活动:
关键路径上的活动称为关键活动。
关键路径可能不只一条,重要的是找到关键活动。
关键路径方案:e[i] == l[i]的边即为关键活动
⑴ 事件的最早发生时间ve[k] :最长的路径长度
ve[1]=0
ve[k]=max{ve[j]+len<vj, vk>} (<vj, vk>∈p[k]) p[k]表示所有到达vk的有向边的集合
⑵ 事件的最迟发生时间vl[k] :vl[k]是指在不推迟整个工期(ve[])的前提下,事件vk允许的最晚发生时间。
vl[n]=ve[n]
vl[k]=min{vl[j]-len<vk, vj>}(<vk, vj>∈s[k]) s[k]为所有从vk发出的有向边的集合
⑶ 活动的最早开始时间e[i]
若活动ai是由弧<vk, vj>表示,则活动ai的最早开始时间应等于事件vk的最早发生时间。因此,有:
e[i]=ve[i]
⑷ 活动的最晚开始时间l[i]
若ai由弧<vk,vj>表示,则ai的最晚开始时间要保证事件vj的最迟发生时间不拖后。因此,有:
l[i]=vl[j]-len<vk, vj>