這是個神奇的算法,感覺沒什麼理由說這麼作肯定能得到最短路,但這麼作確確實實得到的就是最短路。
這或許就是我大學老師常說的神様的力量!
這個算法的操作不難
就是BFS,從起點開始。
每次取出一個點對這個爲起點的距離進行鬆弛操作。
當隊列裏沒有點了,結果就是起點到各個點的最短路。
需要注意的是要用一個數組標記,進入隊列時標成true,
出隊列時標成false。
必須要注意的是鬆弛操作是每進入一個點必須進行,和是否已經標記無關,
在記錄路徑時也是和鬆弛操作一起更新。
標記數組的作用就是看看這個點能不能進隊列,一個點不能重複進兩次隊列。
代碼:
#include <iostream>
using namespace std;
int map[10][10];
int size = 6;
int s = 0, t = 5;
int pre[10];
int q[200];
int vis[10], dis[10];
void init()
{
int i, j;
for(i = 0; i < size; i++)
for(j = 0; j < size; j++)
map[i][j] = 100000;
map[0][1] = 8;
map[0][2] = 4;
map[1][3] = 2;
map[1][4] = 2;
map[2][1] = 4;
map[2][3] = 1;
map[2][4] = -1;
map[3][4] = 6;
map[4][5] = 7;
map[3][5] = 9;
}
int spfa()
{
int i, temp;
for(i = 0; i < size; i++)
{
vis[i] = -1;
dis[i] = 100000;
}
int front = 0, tail= 1;
vis[s] = 1; dis[s] = 0;
q[front] = s;
while(front < tail)
{
temp = q[front];
vis[temp] = -1;
front++;
for(i = 0; i < size; i++)
{
if(dis[i] > dis[temp] + map[temp][i])
{
dis[i] = dis[temp] + map[temp][i];
pre[i] =temp;
if(vis[i] == -1)
{
vis[i] = 1;
q[tail++] = i;
}
}
}
}
return dis[t];
}
int main()
{
int temp;
init();
cout << spfa() << endl;
temp = t; cout << temp << endl;
while(temp != s)
{
cout << pre[temp] << endl;
temp = pre[temp];
}
return 0;
}