Problem4-总结报告

图的相关算法 

图论〔Graph Theory〕是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。

图论,是ACM程序设计这门课的最后一个专题,我觉得也是最难的一个专题,上述所提及的算法,只是图论中算法的极小一部分,图论的综合性比较强,比如有的图论题甚至会用到贪心或搜索的思想,所以遇到具体的问题应该具体的对待。

图论题的另一个特点是模板性非常强,对于常用的算法,只要将其编写成函数,遇到同类问题,只要将现成的函数复制进去,并且修改一下mian()函数和输入输出格式,就可以正确的得出结论。

这里主要就是学了并查集和最小生成树和最短路,最小生成树包括prim算法和kruskal算法最短路常用Dijkstra算法和Bellman-Ford算法 
并查集 
一,常见两种操作: 
合并两个集合 
查找某元素属于哪个集合 
思想:每次查找的时候,如果路径较长,则修改信息,以便下次查找的时候速度更快 
步骤: 
第一步,找到根结点 
第二步,修改查找路径上的所有节点,将它们都指向根结点 

(1)Prim算法: 
基本思想: 
任取一个顶点加入生成树; 
在那些一个端点在生成树里,另一个端点不在生成树里的边中,取权最小的边,将它和另一个端点加进生成树。 
重复上一步骤,直到所有的顶点都进入了生成树为止。

Prim算法一般适用于稠密图。因为prim算法是针对于结点的算法,边的多少与算法的代价关系不太大。 
(2)kruskal算法

kruskal算法的基本思想:
对所有边从小到大排序;

依次试探将边和它的端点加入生成树,如果加入此边后不产生圈,则将边和它的端点加入生成树;否则,将它删去; 
直到生成树中有了n-1条边,即告终止。

算法的时间复杂度O(eloge) 
将边按权值从小到大排序后逐个判断,如果当前的边加入以后不会产生环,那么就把当前边作为生成树的一条边。 
最终得到的结果就是最小生成树。 
一般和并查集一块使用。 
Kruskal算法一般用于稀疏图,kruskal是针对于边的算法,所以边越少越好。 
并查集和最小生成树一般是用于将图连通,求最小代价了或者求最少需要修几条路。这一部分就在那一直修路。 
(3)Dijkstra算法

把顶点集合V分成两组:

 (1)S:已求出的顶点的集合(初始时只含有源点V0)

 

 (2)V-S=T:尚未确定的顶点集合 
将T中顶点按递增的次序加入到S中,保证:

 (1)从源点V0到S中其他各顶点的长度都不大于从V0到T中任何顶点的最短路径长度 

(2)每个顶点对应一个距离值 S中顶点:从V0到此顶点的长度 T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度 
依据:可以证明V0到T中顶点Vk的,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和

求最短路径步骤 
算法步骤如下:

G={V,E} 
1. 初始时令 S={V0},T=V-S={其余顶点},T中顶点对应的距离值 若存在,d(V0,Vi)为弧上的权值 若不存在< V0,Vi>,d(V0,Vi)为∞ 
2. 从T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中 
3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值 重复上述步骤2、3,直到S中包含所有顶点,即W=Vi为止

(4)Bellman-Ford算法: 

Bellman-Ford算法是求含负权图的单源最短路径算法,效率很低,但代码很容易写。其原理为持续地进行松弛(原文是这么写的,为什么要叫松弛,争议很大),在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。Bellman- ford算法有一个小优化:每次松弛先设一个标识flag,初值为FALSE,若有边更新则赋值为TRUE,最终如果还是FALSE则直接成功退出。Bellman-ford算法浪费了许多时间去做没有必要的松弛,而SPFA算法用队列进行了优化,效果十分显著,高效难以想象。SPFA还有SLF,LLL,滚动数组等优化。
算法描述:

1,.初始化:将除源点外的所有顶点的最短距离估计值 d[v] ←+∞, d[s] ←0; 
2.迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次) 
3.检验负权回路:判断边集E中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在 d[v]中。;

注意Dijkstra算法不能处理带有负权值的情况,此时需要用Bellman-Ford算法;

你可能感兴趣的:(Problem4-总结报告)