学习dijkstra已经一周了,学完之后没有温习,以至于今天做题的时候忘了。
当做温习一下吧。
讲一讲dijkstra的主要做法吧。
我们用一个数组s 去存储最短路径上的点(实际上还有标记某点是否被访问的作用)。
还需要用一个dis数组,去储存从起点到某个点的最小距离。(dis[ j ] 就表示从起点到 j 的最短距离)。
如果要求输出路径,我们还可以用一个poineer数组,去记录最短路上某个点的先驱顶点。(其实最好是用栈存放,便于打印路径)
设起点为start , 图用邻接矩阵 matrix[ ][ ] 储存。
我们从起点出发,首先将所有与起点相连的边存在dis数组里。(毫无疑问,起点到 i 的最短距离就是 matrix[ start ][ i ])
然后我们寻找与start相连的最短路。假设为 k, 然后我们以 k 为中间点寻找最短路。若从 start -> k + k ->j < start ->j, 我们就更新start -> j 的最小距离 。
重复上一步,直到所有顶点都被标记。
此时我们得到的dis数组是一个从 start 出发,到其他所有顶点的最短路。
void dijkstra(int start)//int matrix[][], int poineer[][], int dis[]->这些都可以设为全局变量, int f,f为顶点数
{
for(int i = 1; i <= f; i++)
{
dis[i] = matrix[start][i];
s[i] = false;
if(matrix[start][i] < INF)
{
poineer[i] = start;
}
else
poineer[i] = -1;
}
int pos;
s[start] = 1;
dis[start] = 0;
for(int i = 1; i < f; i++)
{
int min = INF;
for(int j = 1; j <= f; j++)
{
if(!s[j] && dis[j] < min)
{
pos = j;
min = dis[j];
}
}
s[pos] = true;
for(int j = 1; j <= f; j++)
{
if(!s[j] && matrix[pos][j] < INF)
if(matrix[pos][j] + dis[pos] < dis[j])
{
poineer[j] = pos;
dis[j] = dis[pos] + matrix[pos][j];
}
}
}
}
接下来讲讲一些注意事项:
1. 给出 从 i - > j 的直接路可能不只一条,我们在储存的时候需要存储最小的那条路。
2.需要进行特殊判断:(1)起点和终点可能根本没有出现(hdu 2112),这个当然是不可达的。(2)起点和终点相同,直接输出0。
3.注意的有向图还是无向图。
4.dijkstra不能处理有负权边的图。