我們這里定義圖的編號為:
1 2 3
4 5 6
7 8 9
圖1:初始化的圖,其中包含邊的權值(耗時)。(這里圖是有向圖)。
圖2:確定起點,然后向能直接走到的點走一下,記錄此時的估計值:2 6 9.。
圖3:找到距離起點最近的點,是正東邊的那個點,這時候我們耗費權值為2。然后我們進行松弛操作,從起點到其東南方的點直接到的權值耗費為6,但是我們通過剛剛選定的點,我們找到了到這個點更近的方式,所以這個時候我們說從起點到其東南方向的點的權值更新值從6變成了5。這個時候我們就完成了第一次松弛操作。
圖4:依舊是找距離起點最近的點。然后松弛我們發現這個時候從起點到其東南方的點的耗費權值從5又變成了4.這個時候我們完成了第二個松弛。
之后的方式同上:選定距離起點最近的點v。然后通過點v進行松弛操作。我們發現能夠通過增加走到目的地方式的復雜度(多轉彎)的方式我們能夠松弛掉權值,使得耗費的權值更小。
模板:
void Dij()//我們這里起點為1號編碼點。我們這里的d[]表示從起點到這個點需要的權值。w[a][b]表示點a到點b這條邊的權值.
{
int i,j,k,v,tmp;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
d[i]=w[1][i];//對應圖不難理解,對於起點的初始化
d[1]=0;
vis[1]=1;
for(i=1;i<=n;i++)//控制連接點的次數,例如上圖,九個點,就循環九次。
{
tmp=N;//這里N表示無窮大。也就是圖上的99.
for(j=1;j<=n;j++)
{
if(tmp>d[j]&&!vis[j])
{
tmp=d[j];
v=j;
}
}//每次我們都找到距離起點最近的點v
vis[v]=1;
for(k=1;k<=n;k++)//然后進行松弛操作。
我們這里的d[]表示從起點到這個點需要的權值//加以強調其含義。
{
if(!vis[k])
d[k]=min(d[k],d[v]+w[v][k]);
}
}
}

