最短路之迪傑克斯拉算法(Dijkstra)

迪傑克斯拉算法(Dijkstra)web

   大意:假設總集合u,剛開始s集合只包括源點v,在集合h(u-s)中找到與v最短距離的k,並將其納入s中,以頂點k爲新考慮的中間點,修改頂點v到h中各頂點的距離:若從源點v到h中某一頂點的距離(通過k點),比原來距離(不通過頂點k)短,則更新該頂點的距離值。如此循環,直到全部頂點都納入s算法

例子:數組

 

Descriptionspa

在每一年的校賽裏,全部進入決賽的同窗都會得到一件很漂亮的t-shirt。可是每當咱們的工做人員把上百件的衣服從商店運回到賽場的時候,倒是很是累的!因此如今他們想要尋找最短的從商店到賽場的路線,你能夠幫助他們嗎?

code

 

Inputorm

輸入包括多組數據。每組數據第一行是兩個整數N、M(N<=100,M<=10000),N表示成都的大街上有幾個路口,標號爲1的路口是商店所在地,標號爲N的路口是賽場所在地,M則表示在成都有幾條路。N=M=0表示輸入結束。接下來M行,每行包括3個整數A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A與路口B之間有一條路,咱們的工做人員須要C分鐘的時間走過這條路。
輸入保證至少存在1條商店到賽場的路線。
ip

 

Outputstring

對於每組輸入,輸出一行,表示工做人員從商店走到賽場的最短期it

 

Sample Inputio

2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0

 

Sample Output

3
2

code:

 

#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3;//找一個較大的數表示路口之間沒路
int map[110][110],dis[110],visited[110];
void Dijkstra(int n,int x)
{
 int i,p,j,min;
 for (i=1;i<=n;i++)
 {
  dis[i]=map[1][i];//從1路口到各路口的距離
  visited[i]=0;//表示未被標記
 }
 visited[x]=1;//將一號標記
 for (i=1;i<=n;i++)
 {
  min=INF;
  for (j=1;j<=n;j++)//找出離1路口最短的路口
  {
   if(!visited[j] && dis[j]<min)
   {
    p=j;
    min=dis[j];
   }
  }
  visited[p]=1;
  for (j=1;j<=n;j++)//更新離1路口最近的距離
  {
   if(!visited[j] && dis[p]+map[p][j]<dis[j])
   {
     dis[j]=dis[p]+map[p][j];
   }
  }
 }
}
int main()
{
 int n,m,i,j,a,b,c;
 while(scanf("%d%d",&n,&m)!=EOF,n+m)
 {
  for (i=1;i<=n;i++)
  {
   for (j=1;j<=n;j++)
   {
    map[i][j]=INF;//初始化
   }
  }
  for(i=1;i<=m;i++)
  {
   scanf("%d%d%d",&a,&b,&c);
   map[a][b]=map[b][a]=c;//二維數組裏存着兩個相連的路口
  }
  Dijkstra(n,1);
  printf("%d\n",dis[n]);
 }
 return 0;
}

 缺點:Dijkstra算法當中將節點分爲已求得最短路徑的集合(記爲S)和未肯定最短路徑的個集合(記爲U),納入S集合的節點的最短路徑及其長度再也不變動,若是邊上的權值容許爲負值,那麼有可能出現當與S內某點(記爲a)以負邊相連的點(記爲b)肯定其最短路徑時,它的最短路徑長度加上這條負邊的權值結果小於a原先肯定的最短路徑長度,而此時a在Dijkstra算法下是沒法更新的,由此即可能得不到正確的結果。求帶負權值邊的單源最短路徑能夠用貝爾曼-福特算法。 

相關文章
相關標籤/搜索