最短路径算法
Posted uninstalllingyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最短路径算法相关的知识,希望对你有一定的参考价值。
弗洛伊德算法(Floyed-Warshall)
适用范围及时间复杂度
该算法的时间复杂度为O(N^3),适用于出现负边权的情况。
可以求取最短路径或判断路径是否连通。可用于求最小环,比较两点之间的大小。
(什么??你不知道什么是负边权??戳->http://t.cn/Ef7pbu6)
核心思想
对于任意一个K点,i到j的距离有两种可能:要么经过k点,要么不经过k点。所以我们只需要不断的迭代k,比较d[i][k]与d[i][k]+d[k][j]的值。如果后者更短,则更新d[i][k]的值。如此重复,最后检查完所有的k时,我们便得到了最短距离。
注意事项及常见问题
由核心思想不难看出,这个算法需要三层循环来实现。但k的位置是值得注意的。经过分析不难发现,k属于最外层循环。
i,j,k三点并不能相同。如若相同,则算法无意义。(自己到自己的距离当然是零啦)
在使用算法时,将map[i][j]值初始为最大/小,map[i][i]一定设置为0(自己到自己当然是零啦)
有时题目会暗含重复数据,也就是相同的路径权重不同。所以要根据题目进行数据比较,更新最大/小的值。
代码实现
初始化:如若两点(假定两点为u,v)相连,则其最短路径初始化为权重。如不相连则初始化为巨大值(0x7ffffff)
1 if(w[u][v]){ 2 dis[u][v]=w[u][v]; 3 }else{ 4 dis[u][v]=0*7ffffff; 5 }
step2:寻找中间点K,比较距离并判断是否更新。
1 for(int k=1;k<=n;k++){ 2 for(int i=1;i<=n;i++){ 3 for(int j=1;j<=n;j++){ 4 if(i!=k&&i!=j&&j!=k){ 5 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 6 } 7 } 8 } 9 }
以上是关于最短路径算法的主要内容,如果未能解决你的问题,请参考以下文章