#define MAXINT 0xfff
#define MAXSIZE 1000
#include<iostream>
#include<string>
using namespace std;
int amapBorder[MAXSIZE][MAXSIZE];
int vNum = 6; //總共有6個頂點元素
void initmap() //這裏是無向圖,初始化隨便造了一個圖,沒有用存儲圖的結構,存儲圖的結構我其他文章裏有。
{
for(int i = 1 ; i < vNum + 1 ; i++)
{
for(int j = 1 ; j < vNum + 1 ; j++)
{
amapBorder[i][j] = MAXINT; //先初始化圖的所有邊都爲無窮大,即沒有邊。
}
}
amapBorder[1][2] = 6;
amapBorder[1][3] = 3;
amapBorder[2][3] = 2;
amapBorder[2][4] = 5;
amapBorder[3][4] = 3;
amapBorder[3][5] = 4;
amapBorder[4][5] = 2;
amapBorder[4][6] = 3;
amapBorder[5][6] = 5; //定義一部分邊,並給出邊權重
for(int i = 1 ; i < vNum + 1 ; i++)
{
for(int j = 1 ; j < vNum + 1 ; j++)
{
if(i == j)
{
amapBorder[i][j] = 0; //頂點與它自身的權重肯定爲0
}
if(amapBorder[i][j] == MAXINT)
{
amapBorder[i][j] = amapBorder[j][i]; //由於是無向圖,所以兩個頂點之間的邊無論什麼方向,權重一樣
}
}
}
}
void dijstra(int vo)
{
int U[7] = {0} //初始化U數組和dist數組所有元素爲0,U[]數組判斷一個頂點是否已經加入得出最短距離的陣營,
int dist[7] = {0}; //dist[]存儲所有頂點到給定點vo最短距離
int path[7]; //存儲該頂點(數組下標)對應的上一個頂點,通過它可以遞歸得出到達該頂點所經過的所有頂點,連起來也就是最短路徑。
/*其實總共是有6個頂點元素的,這裏數組下標0沒有用到,資源浪費了,不過強迫症,不想用0,渴望從1開始*/
for(int i = 1 ; i < vNum + 1 ; i++) //vNum+1是7
{
dist[i] = amapBorder[vo][i]; //dist[i]這裏保存vo-i所經距離,這時候我不知道最短距離,所以先取鄰接矩陣裏的信息,可能是0,可能是數字n,可能是無窮大
if(dist[i] == MAXINT)
{
path[i] = -1; //如果是正無窮,意味着此時,vo到達不了i,沒路,那麼到達i所經歷的最後一個頂點有嗎?沒有,那就給個-1吧,此路不通。
}
else
{
path[i] = vo; //如果有路,那就正常把經過i的最後一個頂點賦給path[i],方便最後遞歸找路。
}
}
for(int i = 1 ; i < vNum + 1 ; i ++)
{
int minNum = MAXINT; //選取出來dist[j]的最小值並把記錄。
int temp = vo;
for( int j = 1 ; j < vNum + 1 ; j++)
{
if((!U[j]) && dist[j] < minNum ) //判斷要求:此時j這個點要在沒得到最小路徑點的陣營裏,並且這個dist[j]小於minNum
{
minNum = dist[j]; //從而篩選出最小的dist[]
temp = j; //記錄最小的dist[]所對應的頂點,j賦值給temp;
}
}
U[temp] = 1; //temp點已找到最短距離,加入找到陣營
for(int j = 1; j < vNum + 1 ; j++)
{
if(!U[j] && amapBorder[temp][j] < MAXINT) //判斷要求:j在未找到陣營裏,且temp-j有路可走,其實有路可走不判斷也行,主要害怕MAXINT這個數太大跟dist[temp]相加溢出。
{
if(dist[j] > amapBorder[temp][j] + dist[temp]) //如果vo到temp的距離(最短距離)+ temp到j的距離 比原來vo直接到j距離短,則更新dist[j]
{
dist[j] = amapBorder[temp][j] + dist[temp];
path[j] = temp; //記錄path[j]經過的最後一個點,至少當前這個點事temp,以後可能還要變。
}
}
}
}
for(int i = 1; i < vNum + 1 ; i++) //打印vo到各個頂點最短距離,以及路徑
{
cout << i << ": " << dist[i] << '\t';
int j = i;
cout << j << "<-";
while(path[j] != vo) //遞歸path[]找出到一個頂點經過的所有頂點,倒序列出來,當然可以轉換爲正序。
{
j = path[j];
cout << j << "<-";
}
cout << vo << endl;
}
}
dijkstra算法求單源最短路徑
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.