这两个算法都是用来求最短路径的算法,主要区别就是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; else e[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; }