SPFA算法

這是個神奇的算法,感覺沒什麼理由說這麼作肯定能得到最短路,但這麼作確確實實得到的就是最短路。

這或許就是我大學老師常說的神様的力量!


這個算法的操作不難

就是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;  
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章