原理解析
http://blog.csdn.net/wizard_wsq/article/details/51095853
小技巧总结
图用邻接矩阵表示
Distance[i]表示v0到顶点i的距离
int prev[i]表示节点v0到节点i存在最短路径时,其前一个节点。
Dijkstra代码
//Dijkstra算法函数,求给定顶点到其余各点的最短路径
//参数:邻接矩阵、出发点的下标、结果数组、路径前一点记录
//Graph[][N],表示加权有向图的邻接矩阵,其中Graph[i][j]=M=65536,表示i到j不可直接到达
//v0表示以v0顶点开始寻找到其他顶点的距离
//Distance[i]表示v0到顶点i的距离
//prev[]表示
void Dijkstra(int Graph[][N], int v0, int Distance[], int prev[])
{
bool visited[N];//表示是否已经访问过
int i, j, u;
//初始化
for (int i = 0; i<N; i++)
{
Distance[i] = Graph[v0][i];//包含了Distance[v0] = 0;
visited[i] = 0;
if (Distance[i] == M)
prev[i] = -1;
else
prev[i] = v0;
}
visited[v0] = 1;
for (i = 1; i < N; i++)//每循环一次,求得一个最短路径
{
int mindis=M, dis;//在当前还未找到最短路径的顶点中,寻找具有最短距离的顶点
u = v0;
for (j = 0; j < N; j++) //求离出发点最近的顶点
if (visited[j] == 0 && Distance[j]<mindis)
{
mindis = Distance[j];
u = j;
}
visited[u] = 1;
for (j = 0; j<N; j++) //由于新增了顶点u,所以要更新每个未被访问的顶点的distance。只会由u来影响
if (visited[j] == 0 && Graph[u][j]<M)
{ //对还未求得最短路径的顶点。求出由最近的顶点 直达各顶点的距离
dis = Distance[u] + Graph[u][j];
// 如果新的路径更短,就替换掉原路径
if (Distance[j] > dis)
{
Distance[j] = dis;
prev[j] = u;
}
} // if 语句体结束,j循环结束
} // i循环结束
}
Test代码
#pragma once
#include<iostream>
#include <cstdio>
#include <list>
#include <vector>
#include <queue>
#include<stack>
#include<fstream>
#define M 65535 //无穷大
#define N 5 //顶点数
//Dijkstra算法函数,求给定顶点到其余各点的最短路径
//参数:邻接矩阵、出发点的下标、结果数组、路径前一点记录
//Graph[][N],表示加权有向图的邻接矩阵,其中Graph[i][j]=M=65536,表示i到j不可直接到达
//v0表示以v0顶点开始寻找到其他顶点的距离
//Distance[i]表示v0到顶点i的距离
//prev[]表示
void Dijkstra(int Graph[][N], int v0, int Distance[], int prev[])
{
bool visited[N];//表示是否已经访问过
int i, j, u;
//初始化
for (int i = 0; i<N; i++)
{
Distance[i] = Graph[v0][i];//包含了Distance[v0] = 0;
visited[i] = 0;
if (Distance[i] == M)
prev[i] = -1;
else
prev[i] = v0;
}
visited[v0] = 1;
for (i = 1; i < N; i++)//每循环一次,求得一个最短路径
{
int mindis=M, dis;//在当前还未找到最短路径的顶点中,寻找具有最短距离的顶点
u = v0;
for (j = 0; j < N; j++) //求离出发点最近的顶点
if (visited[j] == 0 && Distance[j]<mindis)
{
mindis = Distance[j];
u = j;
}
visited[u] = 1;
for (j = 0; j<N; j++) //由于新增了顶点u,所以要更新每个未被访问的顶点的distance。只会由u来影响
if (visited[j] == 0 && Graph[u][j]<M)
{ //对还未求得最短路径的顶点。求出由最近的顶点 直达各顶点的距离
dis = Distance[u] + Graph[u][j];
// 如果新的路径更短,就替换掉原路径
if (Distance[j] > dis)
{
Distance[j] = dis;
prev[j] = u;
}
} // if 语句体结束,j循环结束
} // i循环结束
}
// 参数:路径前一点记录、出发点的下标、到达点下标
void PrintPrev(int prev[], int v0, int vn)
{
int tmp = vn;
int i, j;
//临时存路径
int tmpprv[N];
//初始化数组
for (i = 0; i < N; i++)
tmpprv[i] = 0;
//记录到达点下标
tmpprv[0] = vn + 1;
//中间点用循环记录
for (i = 0, j = 1; j < N; j++)
{
if (prev[tmp] != -1 && tmp != 0)
{
tmpprv[i] = prev[tmp] + 1;
tmp = prev[tmp];
i++;
}
else break;
}
//输出路径,数组逆向输出
for (i = N - 1; i >= 0; i--)
{
if (tmpprv[i] != 0)
{ //排除0元素
printf("V%d", tmpprv[i]);
if (i) //不是最后一个输出符号
printf("-->");
}
}
printf("-->V%d", vn + 1);
}
//主函数
void test_dijkstra()
{
//给出有向网的顶点数组
char *Vertex[N] = { "V1", "V2", "V3", "V4", "V5" };
//给出有向网的邻接矩阵
int Graph[N][N] = {
{ 0, 10, M, 30, 100 },
{ M, 0, 50, M, M },
{ M, M, 0, M, 10 },
{ M, M, 20, 0, 60 },
{ M, M, M, M, 0 },
};
int Distance[N]; //存放求得的最短路径长度
int prev[N]; //存放求得的最短路径
int i;
//调用Dijkstra算法函数,求顶点V1到其余各点的最短路径
//参数:邻接矩阵、出发点的下标、结果数组、路径前一点记录
Dijkstra(Graph, 0, Distance, prev);
for (i = 0; i < N; i++)
{
//输出最短路径长度
cout << Vertex[0] << " " << Vertex[i] << " " << Distance[i]<<" ";
//printf("%visited-->%visited:%d\t", Vertex[0], Vertex[i], Distance[i]);
//输出最短路径
PrintPrev(prev, 0, i);
printf("\n");
}
}