Dijkstra算法用于解决最短路问题,其时间复杂度为o(n^2)。
该算法大体步骤如下:
设定一个顶点集合,首先将源点加入集合内,接下来找距离远点最近距离的一个点,将其加入到集合内,用它来更新不在集合内的所有与它相连的源点能到达的点的距离,然后不断进行这个操作,n-1次之后就更新完了所有的点。
查找不在集合内的源点所能到达的最近的点并加入集合:
for(int j = 1; j <= poi_num; j++){
if(!vis[j] && Min > d[j]){
poi_temp = j;
Min = d[j];
}
}
vis[poi_temp] = 1;
用它来更新相连的不在集合内的点与源点之间的距离(松弛):
for(int j = 1; j <= poi_num; j++){
if(!vis[j] && d[j] > d[poi_temp] + map[poi_temp][j]){
d[j] = d[poi_temp] + map[poi_temp][j];
}
}
完整代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
#define M 10000
const int Max = 0x3f3f3f3f;
bool vis[M];
int d[M];
int Map[M][M];
void init(int n)
{
int i, j;
for(i = 0; i < n; i++){
d[i] = Max;
for(j = 0; j < n; j++){
Map[i][j] = Max;
}
}
memset(vis, 0, sizeof(vis));
}
void Dijkstra(int poi_be, int n)
{
int i, j, t, Min;
for(i = 1; i <= n; i++){
d[i] = Map[poi_be][i]; //d[i]代表源点到i点的当前最短路径
}
vis[poi_be] = 1; //poi_be为起始点代表起始点已加入集合
d[poi_be] = 0;
for(i = 1; i < n; i++){
Min = Max;
for(j = 1; j <= n; j++){ //寻找当前最短路径
if(!vis[j] && Min > d[j]){
t = j;
Min = d[j];
}
}
vis[t] = 1; //找到并加入集合
for(j = 1; j <= n; j++){
if(!vis[j] && Min + Map[t][j] < d[j]) //松弛,更新相连的不在集合内的点与源点之间的距离
d[j] = Min + Map[t][j];
}
}
}
int main()
{
int poi_n, edge_n, poi_be, poi_en, i;
cin >> poi_n >> edge_n;
init(poi_n);
for(i = 0; i < edge_n; i++){
int poi_a, poi_b, len;
cin >> poi_a >> poi_b >> len;
Map[poi_a][poi_b] = len;
Map[poi_b][poi_a] = len;
}
cin >> poi_be >> poi_en;
Dijkstra(poi_be, poi_n);
cout << d[poi_en] << endl;
return 0;
}
半转载自http://blog.youkuaiyun.com/crazyforsaken/article/details/79161529