赞
踩
最短路是图论最重要的算法之一,也是算法难点。经过这篇的学习,你会发现你离成功就差一个最短路的距离。=.=
最短路是指,某个点到某个点之间的距离最短。
迪杰斯特拉算法是很典型的单源最短路算法,而且时间复杂度较其他算法更低,唯一的缺点是无法判断含负权边的图的最短路。而且其仅能作为单源最短路,也就是一个起点、一个终点求最短。在开始前推荐大家先去看我的另一篇博客最小生成树其中的prim算法和这个很类似。
同样由于技术有限,仅靠文字和代码讲解。-_-
int pic[1005][1005];//存图
在输入之前,初始化图,将各点之间的距离设置为最大值,表示无法到达。
这里的图是单向的。
void init()
{
for(int i=0;i<1005;i++)
{
for(int j=0;j<1005;j++)
{
pic[i][j]=(1<<21);//最大值可以自己设定,只要能表示不可达即可
}
}
}
dijkstra模板函数如下
特别强调c++和java不同,新开的数组会沿用之前相同名字的内存地址,所以赋值false很关键。之前我的模板错误在此
另外注意起点下标0-n-1或者1-n需要更改
void dijkstra() { int weight[1005];//起始到其他端点的值 bool visit[1005]; for(int i=0;i<n;i++) { weight[i]=pic[0][i];//将图中0到各个端点的值赋给weight数组 visit[i]=false; } weight[0]=0; visit[0]=true; //此时起点为0 while(true)//0点作为起始点,从下一个点开始 { int j=0,k=-1,min=(1<<21); //weight内的值为0时表示,已经访问过 //遍历weight数组,寻找一个最小值,并且该点没有被访问过 while(j<n) { if(min>weight[j]&&!visit[j]) { min=weight[j]; k=j;//用k存下这个节点 } j++; } //已知的min是我当前起始节点到k节点的距离,已知连接边中最短的 if(k==-1) break; visit[k]=true;//访问过该节点 //自此形成从起始到K的边,将其连接 for(int m=0;m<n;m++) { if(weight[m]>pic[k][m]+weight[k]&&!visit[m]) { weight[m]=pic[k][m]+weight[k]; //将单点间距离与新更新值距离比较求最小 } } } }
和prim唯一一点不同的是,其他点存的距离为一段距离,未连接之前是最大值,连接过后就是某一段加某一段,weight数组里面存的是起始点到各点之间的距离。
唯一的缺点就是时间复杂度过高(On^3),在算法实现时需要注意arr[i][k]+arr[k][j]的溢出问题所以可能需要long long数组。
void floyd()//算法模板
{
for(int k=0;k<=n;k++)
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
if(arr[i][j]>arr[i][k]+arr[k][j])
arr[i][j]=arr[i][k]+arr[k][j];
}
n表示点的个数,arr里面存取的是点到点的路径值,经过算法计算后,点到点的距离即为最小,可以求各个点之间的。
之前遗漏,有待补充
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。