说是总结,其实自己也没有学多长时间只是把自己这段时间的一些经验总结下来,用来供后来的初学者涨点经验吧。对于学习算法,个人的理解就是首先要去理解算法的本质,然后想想算法的实现过程,如何用代码去描述这个算法,然后就是去记模板了(对于像我这种初学者来说,这一步其实蛮重要的)。另外说下做最短路问题的一些容易出错的地方。1、要小心重边,就是题目会给你一些边类似于2 4 5,2 4 3;这种边和权值的。2、要注意图中所给的是有向图还是无向图,一般情况下都是无向图的,如果有特殊说明的话,就是有向图。接下来我就以HDU的1874--畅通工程续这道题来简单分析一下这三种算法。
第一、dijkstra算法:这种算法只能解决权值不是负的图(稍后解释一下为什么权值不能为负)。
特点:可以求出单源点到其他顶点的最短距离,算法的复杂程度比floyd算法稍微低一些。
算法描述:比较类似于求最小生成树中的prime算法,设置一个点集合S,然后用贪心的方式去选择扩充这个集合。就是说如果1到3的距离为5,1到2为1,同时2到3为2;那么这个时候dis[3]应该=3;即用DIS数组来存储每个点到远点的最短距离,并不断更新这个最短距离,当所有的点都加入了集合S时就可以跳出循环了。
缺点:不能解决带负权值的图,如果图很大的话也不是很好处理,可能会需要用邻接表,这个没试过,图很大的话一般都用SPFA了。为什么不能解决负权值问题?归入S集合的节点的最短路径及其长度不再变更,如果边上的权值允许为负值,那么有可能出现当与S内某点(记为a)以负边相连的点(记为b)确定其最短路径时,它的最短路径长度加上这条负边的权值,结果小于a原先确定的最短路径长度,而此时a在Dijkstra算法下是无法更新的,由此便可能得不到正确的结果。(标记一下,醒目些)。
代码实现的过程(用HDU--1874--畅通工程续--来举例,题目自搜哦)