Floyd和Dijkstra的最短路

来源:互联网 发布:人工智能相关论文 编辑:程序博客网 时间:2024/05/22 03:47

Floyd和Dijkstra的最短路问题

这两个算法都是用来求最短路径的算法,主要区别就是Floyd求的是任意两点之间的最短路值,Dijkstra主要求得是单源最短路,就是一个点到其他点的最短路值,二者都不能解决负权值问题。
弗洛伊德算法(Floyd算法)主要是用了一种“松弛”的方法,就是在从a到b的路线中是否能够找到一个中转点,比如说k点,就是dis[a][k]+dis[k][b]的值小于dis[a][b]的时候,可以从a出发先到k点,再转到b点,这样就可以达到题中最短的目的,然后以此类推。将已知所有点都作为中转点,进行一轮轮的比较。核心代码就只有5行,比较简单暴力。
for(k=1;k<=n;k++)//最外层的循环表示中转点的更新for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(e[i][j]>e[i][k]+e[k][j])//这里有一个稍难理解的一点,就是e[i][k],e[k][j]是经过之前几次中转后得到的最优解,所以可以中转几次的情况e[i][j]=e[i][k]+e[k][j];
迪杰斯特拉算法(Dijkstra算法)是求单源最短路的一个算法,核心代码也不多,主要一个思想就是找到确定的最短距离的点,然后对其他点进行松弛的处理,标记已知是最短距离的点,然后根据点的数量确定循环结束。
#include <stdio.h>#include <string.h>int e[10010][10010];int dis[10010],book[10010];int inf=99999999;int main(){int a,b,c,n,m;int i,j,k,u,s,min;while(scanf("%d%d",&n,&m)!=EOF){for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(i==j)e[i][j]=0;elsee[i][j]=inf;}for(i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);if(c<e[a][b])//从一个地点到另外一个地点的路可能不止一条,只保存最短的一条这里有时候会坑 e[a][b]=c;}memset(dis,0,sizeof(dis));memset(book,0,sizeof(book));for(i=1;i<=n;i++)dis[i]=e[1][i];//这里的源点是1点book[1]=1;for(s=1;s<n;s++)//循环n-1次,将除源点之外的n-1个点找出来{min=inf;//寻找距源点最近的未标记的点 for(i=1;i<=n;i++)if(book[i]==0&&dis[i]<min){min=dis[i];u=i;}book[u]=1;for(k=1;k<=n;k++)//从确定距离源点最近的已知点出发,对每个点进行比较 {if(e[u][k]<inf)//确认两点之间是存在路径的{if(dis[k]>dis[u]+e[u][k])dis[k]=dis[u]+e[u][k];}}}for(i=1;i<=n;i++)printf("%d ",dis[i]);}return 0;}

原创粉丝点击