亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Dijkstra算法最短路徑的C++實現(xiàn)與輸出路徑

 更新時間:2019年02月20日 14:48:50   作者:田園園野  
今天小編就為大家分享一篇關于Dijkstra算法最短路徑的C++實現(xiàn)與輸出路徑,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

某個源點到其余各頂點的最短路徑

這個算法最開始心里怕怕的,不知道為什么,花了好長時間弄懂了,也寫了一遍,又遇到時還是出錯了,今天再次寫它,心里沒那么怕了,耐心研究,懂了之后會好開心的,哈哈

Dijkstra算法:

圖G

如圖:若要求從頂點1到其余各頂點的最短路徑,該咋求;

迪杰斯特拉提出“按最短路徑長度遞增的次序”產生最短路徑。

首先,在所有的這些最短路徑中,長度最短的這條路徑必定只有一條弧,且它的權值是從源點出發(fā)的所有弧上權的最小值,例如:在圖G中,從源點1出發(fā)有3條弧,其中以?。?,2)的權值為最小,因此,(1,2)不僅是1到2的一條最短路徑,并且它可能是源點到其它各個終點的最短路徑中的一條子路徑。

其次,第二條長度次短的最短路徑只可能有兩種情況:①它或者只含一條從源點出發(fā)的弧且弧上的權值大于已求得最短路徑的那條弧的權值,但小于其他從源點出發(fā)的弧上的權值②它或者是一條只經過已求得最短路徑的頂點的路徑。

例如圖G中,從1到其他各點。過程中,用d[i]保存從1到i的的最短路徑(過程會變化),初值為:若源點到該源點有弧,則為權值,否則初始化為無窮大,每求得一條到達某個終點i的最短路徑,就繼續(xù)檢查是否存在以此路徑為子路徑的到達其他點的最短路徑,若存在,判斷其長度是否比當前求得的路徑長度短,若短,就更新為更短的長度。

如圖G中,求得到2的最短路徑d[2]為10,就把d[2]作為與2相連的到其他點的子路徑繼續(xù)檢查,得到到3的最短路徑為d[2]+50=60

過程:

(1).令S={1},S集合中表示已經找到最短路徑的結點,開始時1為源點,并設定d[i]的初始值為:d[i]=(1,i),

(2).求出到j點的最短路徑,j點為不在S集合中的某點

d[j]=min{d[i]}

(3).判斷所有沒在S集合中的頂點k,若d[k]>d[j]+(j,k)則修改d[k]的值為:

d[k]=d[j]+(j,k)

(4).重復(2).(3)操作共n-1次,每次操作,在(2)得到一個到

某點的最短路徑。

有向圖求最短路徑

#include<stdio.h>
#include<string.h> 
#include<stdlib.h>
#define max 900000000
//有向圖 
int main(){
  int n,m,a,b,v,i,j,min,k;
  scanf("%d%d",&n,&m);//輸入n個頂點,m條邊 
  int g[n+1][n+1],d[n+1],vis[n+1];//g[i][j]表示i到j的邊的權值,vis[i]表示到此頂點的最短路是否已經找到,d[i]當前源點到i頂點的最短路徑 
  memset(vis,0,sizeof(vis));
  for(i=0;i<=n;i++){ 
    for(j=0;j<=n;j++){
      g[i][j]=max;
    }
    d[i]=max;  
  }
  for(i=0;i<m;i++){//i到j的邊權值儲存到g鄰接矩陣中,i點到j點無直接相連的邊時,g[i][j]=max 
    scanf("%d%d%d",&a,&b,&v);
    g[a][b]=v;
  }
  for(i=2;i<=n;i++){
      d[i]=g[1][i]; //初始化源點到i點邊權值,之后過程中會發(fā)生變化 
  }
  vis[1]=1;
  for(i=2;i<=n;i++){//共循環(huán)n-1次,每循環(huán)一次,確定一條最短路,再次循環(huán)時這條路就不用考慮了,去尋找下一條最短路 
    min=max;
    for(j=2;j<=n;j++){//尋找下一條當前最短路 
      if(d[j]<min&&vis[j]==0){
       min=d[j];
       k=j;
      }  
    }
    vis[k]=1;//找到了,到k點的路是當前最短路,標記它,根據它尋找下一條最短路 
    for(j=2;j<=n;j++){
      if(d[j]>d[k]+g[k][j]&&vis[j]==0){//經過此k點到達j點的路徑是否小于其他到達j點的路徑 
        d[j]=d[k]+g[k][j];
      }
    }
  }  
  for(i=2;i<=n;i++){//輸出到達個點的最短路徑 
    printf("%d\n",d[i]);
  }
  return 0;
}

無向圖求最短路徑

無向圖也是相同思路:在構造鄰接矩陣時考慮對稱就行。

無向圖求最短路徑且有路徑輸出

在求最短路的過程中,最短路①它或者是從源點出發(fā)的?、谒蛘呤且粭l經過已到其他最短路徑的頂點的路徑。

建立一個新的結構體類型path,該類型變量d表示到達某點的最短路徑距離 ,該類型變量pre表示該最短路徑是經過哪個點傳過來的

#include<stdio.h>
#include<string.h> 
#include<stdlib.h>
#define max 900000000
typedef struct{ 
  int d;//到達某點的最短路徑距離 
  int pre;//該最短路徑是經過哪個點傳過來的,源點或其他某個點 
}path;
//有向圖 
int main(){
  int n,m,a,b,v,i,j,min,k,from;
  scanf("%d%d",&n,&m);//輸入n個頂點,m條邊 
  int g[n+1][n+1],vis[n+1];//g[i][j]表示i到j的邊的權值,vis[i]表示到此頂點的最短路是否已經找到,d[i]當前源點到i頂點的最短路徑 
  path to[n+1];//記錄當前到某個點的最短路徑以及從哪個點傳過來的 
  memset(vis,0,sizeof(vis));
  for(i=0;i<=n;i++){ 
    for(j=0;j<=n;j++){
      g[i][j]=max;
    }
    to[i].d=max;  
  }
  for(i=0;i<m;i++){//i到j的邊權值儲存到g數組中,i點到j點無直接相連的邊時,g[i][j]=max 
    scanf("%d%d%d",&a,&b,&v);
    g[a][b]=v;
    g[b][a]=v;
  }
  for(i=2;i<=n;i++){
      to[i].d=g[1][i]; //初始化源點到i點邊權值,之后過程中會發(fā)生變化 
      if(g[1][i]!=max){
       to[i].pre=1; 
      } 
  }
  vis[1]=1;
  for(i=2;i<=n;i++){//共循環(huán)n-1次,每循環(huán)一次,確定一條最短路,再次循環(huán)時這條路就不用考慮了,去尋找下一條最短路 
    min=max;
    for(j=2;j<=n;j++){//尋找下一條當前最短路 
      if(to[j].d<min&&vis[j]==0){
       min=to[j].d;
       k=j;
      }  
    }
    vis[k]=1;//找到了,到k點的路是當前最短路,標記它,根據它尋找下一條最短路 
    for(j=2;j<=n;j++){
      if(to[j].d>to[k].d+g[k][j]&&vis[j]==0){//經過此k點到達j點的路徑是否小于其他到達j點的路徑 
        to[j].d=to[k].d+g[k][j];
        to[j].pre=k;//改變j點是誰傳來的,現(xiàn)在到j點的最短路徑是經過k點的,由j點傳來 
      }
    }
  }  
  for(i=2;i<=n;i++){//輸出到達個點的最短路徑 
    printf("%d ",to[i].d);
    printf("%d ",i);
    j=i;
    while(j!=1){
      j=to[j].pre;
      printf("%d ",j);
    }
    printf("\n");
  }
  return 0;
}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內容請查看下面相關鏈接

相關文章

  • C++中的STL常用算法之遍歷算法詳解

    C++中的STL常用算法之遍歷算法詳解

    這篇文章主要介紹了C++中的STL常用算法之遍歷算法詳解,ransform() 可以將函數應用到容器的元素上,并將這個函數返回的值保存到另一個容器中,它返回的迭代器指向輸出容器所保存的最后一個元素的下一個位置,需要的朋友可以參考下
    2023-12-12
  • 深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言中函數棧幀的創(chuàng)建和銷毀的深層分析

    C語言中函數棧幀的創(chuàng)建和銷毀的深層分析

    在C語言中,每一個正在運行的函數都有一個棧幀與其對應,棧幀中存儲的是該函數的返回地址和局部變量。從邏輯上講,棧幀就是一個函數執(zhí)行的環(huán)境:函數參數、函數的局部變量、函數執(zhí)行完后返回到哪里等等
    2022-04-04
  • Linux配置C++11編譯環(huán)境的方法

    Linux配置C++11編譯環(huán)境的方法

    這篇文章主要介紹了Linux配置C++11編譯環(huán)境,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • 利用c++編寫簡易版2048小游戲

    利用c++編寫簡易版2048小游戲

    這篇文章主要介紹了如何讓利用c++編寫簡易版的2048小游戲,感興趣的小伙伴請參考下面文章的具體內容
    2021-09-09
  • c++11多種格式時間轉化為字符串的方法實現(xiàn)

    c++11多種格式時間轉化為字符串的方法實現(xiàn)

    本文主要介紹了c++11多種格式時間轉化為字符串的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++實現(xiàn)LeetCode(163.缺失區(qū)間)

    C++實現(xiàn)LeetCode(163.缺失區(qū)間)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(163.缺失區(qū)間),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • C++實現(xiàn)二分法求方程近似解

    C++實現(xiàn)二分法求方程近似解

    這篇文章主要為大家詳細介紹了C++實現(xiàn)二分法求方程近似解,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++實現(xiàn)LeetCode(39.組合之和)

    C++實現(xiàn)LeetCode(39.組合之和)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(39.組合之和),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • C語言示例講解do?while循環(huán)語句的用法

    C語言示例講解do?while循環(huán)語句的用法

    在不少實際問題中有許多具有規(guī)律性的重復操作,因此在程序中就需要重復執(zhí)行某些語句。一組被重復執(zhí)行的語句稱之為循環(huán)體,能否繼續(xù)重復,決定循環(huán)的終止條件
    2022-06-06

最新評論