最短路径是三种求法

说是总结,其实自己也没有学多长时间只是把自己这段时间的一些经验总结下来,用来供后来的初学者涨点经验吧。对于学习算法,个人的理解就是首先要去理解算法的本质,然后想想算法的实现过程,如何用代码去描述这个算法,然后就是去记模板了(对于像我这种初学者来说,这一步其实蛮重要的)。另外说下做最短路问题的一些容易出错的地方。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--畅通工程续--来举例,题目自搜哦)

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #define INF 0x3f3f3f3f  
  4. int vis[210],map[210][210],dis[210],n,m,beg,end;  
  5. void init(){  
  6.     for(int i=0;i<n;i++)  
  7.         for(int j=0;j<n;j++){  
  8.             if(i==j)//如果是自己到自己的距离,那当然为0咯。   
  9.                 map[i][j]=map[j][i]=0;  
  10.             else  
  11.                 map[i][j]=map[j][i]=INF;//最开始点都是不连通的   
  12.         }  
  13. }  
  14. void dijkstra(){ //dijk算法的核心 (借鉴了prime算法的实现过程)   
  15.     int i,flag=0;  
  16.     memset(vis,0,sizeof(vis));//用这个来标记点是否使用过,或者说是否进入集合S。   
  17.     for(i=0;i<n;i++)  
  18.         dis[i]=map[beg][i];//初始化距离,并把起点当做源点加入集合。   
  19.     vis[beg]=1;//标记源点   
  20.     for(i=0;i<n;i++){  
  21.         int j,k,temp=INF;  
  22.         for(j=0;j<n;j++)  
  23.             if(!vis[j]&&temp>dis[j])  
  24.                 temp=dis[k=j];  
  25.         vis[k]=1;  
  26.         
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值