日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

迪杰斯特拉--- 模板(求最短路径/输出路径/所有路径都可以走的做法)

發布時間:2024/6/18 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 迪杰斯特拉--- 模板(求最短路径/输出路径/所有路径都可以走的做法) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
迪杰斯特拉--- 模板(求最短路徑/輸出路徑/所有路徑都可以走的做法)

1.0版

#include <iostream> using namespace std;const int maxnum = 100; const int maxint = 999999;// 各數組都從下標1開始 int dist[maxnum]; // 表示當前點到源點的最短路徑長度 int prev[maxnum]; // 記錄當前點的前一個結點 int c[maxnum][maxnum]; // 記錄圖的兩點間路徑長度 int n, line; // 圖的結點數和路徑數// n -- n nodes // v -- the source node // dist[] -- the distance from the ith node to the source node // prev[] -- the previous node of the ith node // c[][] -- every two nodes' distance void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum]) {int i,j;bool s[maxnum]; // 判斷是否已存入該點到S集合中for(i=1; i<=n; ++i){dist[i] = c[v][i];s[i] = 0; // 初始都未用過該點if(dist[i] == maxint)prev[i] = 0;elseprev[i] = v;}dist[v] = 0;s[v] = 1;// 依次將未放入S集合的結點中,取dist[]最小值的結點,放入結合S中// 一旦S包含了所有V中頂點,dist就記錄了從源點到所有其他頂點之間的最短路徑長度// 注意是從第二個節點開始,第一個為源點for(i=2; i<=n; ++i){int tmp = maxint;int u = v;// 找出當前未使用的點j的dist[j]最小值for(j=1; j<=n; ++j)if((!s[j]) && dist[j]<tmp){u = j; // u保存當前鄰接點中距離最小的點的號碼tmp = dist[j];}s[u] = 1; // 表示u點已存入S集合中// 更新distfor(j=1; j<=n; ++j)if((!s[j]) && c[u][j]<maxint){int newdist = dist[u] + c[u][j];if(newdist < dist[j]){dist[j] = newdist;prev[j] = u;}}} }// 查找從源點v到終點u的路徑,并輸出 void searchPath(int *prev,int v, int u) {int que[maxnum];int tot = 1;que[tot] = u;tot++;int tmp = prev[u];while(tmp != v){que[tot] = tmp;tot++;tmp = prev[tmp];}que[tot] = v;//輸出路徑for(int i=tot; i>=1; --i)if(i != 1)cout << que[i] << " -> ";elsecout << que[i] << endl; }int main() {int i,j; // freopen("input.txt", "r", stdin);// 各數組都從下標1開始// 輸入結點數cin >> n;// 輸入路徑數cin >> line;int p, q, len; // 輸入p, q兩點及其路徑長度// 初始化c[][]為maxintfor(i=1; i<=n; ++i)for(j=1; j<=n; ++j)c[i][j] = maxint;for(i=1; i<=line; ++i) {cin >> p >> q >> len;if(len < c[p][q]) // 有重邊{c[p][q] = len; // p指向qc[q][p] = len; // q指向p,這樣表示無向圖}}for(i=1; i<=n; ++i)dist[i] = maxint;//輸出矩陣-------for(i=1; i<=n; ++i){for(j=1; j<=n; ++j)printf("%8d", c[i][j]);printf("\n");}Dijkstra(n, 1, dist, prev, c);// 最短路徑長度cout << "源點到最后一個頂點的最短路徑長度: " << dist[n] << endl;// 路徑cout << "源點到最后一個頂點的路徑為: ";searchPath(prev, 1, n);return 0; } /* 測試數據: 4 4 1 2 1 2 3 1 3 4 1 1 4 4*/

1.1版 任意兩點(ps:未解決負權)

#include <iostream> using namespace std;const int maxnum = 100; const int maxint = 999999;// 各數組都從下標1開始 int dist[maxnum]; // 表示當前點到源點的最短路徑長度 int prev[maxnum]; // 記錄當前點的前一個結點 int c[maxnum][maxnum]; // 記錄圖的兩點間路徑長度 int n, line; // 圖的結點數和路徑數// n -- n nodes // v -- the source node // dist[] -- the distance from the ith node to the source node // prev[] -- the previous node of the ith node // c[][] -- every two nodes' distance void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum]) {int i,j;bool s[maxnum]; // 判斷是否已存入該點到S集合中for(i=1; i<=n; ++i){dist[i] = c[v][i];s[i] = 0; // 初始都未用過該點if(dist[i] == maxint)prev[i] = 0;elseprev[i] = v;}dist[v] = 0;s[v] = 1;// 依次將未放入S集合的結點中,取dist[]最小值的結點,放入結合S中// 一旦S包含了所有V中頂點,dist就記錄了從源點到所有其他頂點之間的最短路徑長度// 注意是從第二個節點開始,第一個為源點for(i=2; i<=n; ++i){int tmp = maxint;int u = v;// 找出當前未使用的點j的dist[j]最小值for(j=1; j<=n; ++j)if((!s[j]) && dist[j]<tmp){u = j; // u保存當前鄰接點中距離最小的點的號碼tmp = dist[j];}s[u] = 1; // 表示u點已存入S集合中// 更新distfor(j=1; j<=n; ++j)if((!s[j]) && c[u][j]<maxint){int newdist = dist[u] + c[u][j];if(newdist < dist[j]){dist[j] = newdist;prev[j] = u;}}} }// 查找從源點v到終點u的路徑,并輸出 void searchPath(int *prev,int v, int u) {int que[maxnum];int tot = 1;que[tot] = u;tot++;int tmp = prev[u];while(tmp != v){que[tot] = tmp;tot++;tmp = prev[tmp];}que[tot] = v;//輸出路徑for(int i=tot; i>=1; --i)if(i != 1)cout << que[i] << " -> ";elsecout << que[i] << endl; }int main() {int i,j; // freopen("input.txt", "r", stdin);// 各數組都從下標1開始// 輸入結點數cin >> n;// 輸入路徑數cin >> line;int p, q, len; // 輸入p, q兩點及其路徑長度// 初始化c[][]為maxintfor(i=1; i<=n; ++i)for(j=1; j<=n; ++j)c[i][j] = maxint;for(i=1; i<=line; ++i) {cin >> p >> q >> len;if(len < c[p][q]) // 有重邊{c[p][q] = len; // p指向qc[q][p] = len; // q指向p,這樣表示無向圖}}for(i=1; i<=n; ++i)dist[i] = maxint;//輸出矩陣-------for(i=1; i<=n; ++i){for(j=1; j<=n; ++j)printf("%8d", c[i][j]);printf("\n");}int begin,end;printf("輸入起點和終點\n");scanf("%d%d",&begin,&end);Dijkstra(end, begin, dist, prev, c);// 最短路徑長度cout << "點A到點B的最短路徑長度: " << dist[n] << endl;// 路徑cout << "點A到點B的路徑為: ";searchPath(prev, begin, end);return 0; } /* 測試數據: 4 4 1 2 1 2 3 1 3 4 1 1 4 4 2 2 cout<< 2 2->3->4 */


if 題目要求的是每兩點之間的路都可以走或可以求的話,用下面方法


#include <iostream> using namespace std;const int maxnum = 100; const int maxint = 999999;struct Point{double x;double y;double len; }p[250]; // 各數組都從下標1開始 int dist[maxnum]; // 表示當前點到源點的最短路徑長度 int prev[maxnum]; // 記錄當前點的前一個結點 int c[maxnum][maxnum]; // 記錄圖的兩點間路徑長度 int n, line; // 圖的結點數和路徑數// n -- n nodes // v -- the source node // dist[] -- the distance from the ith node to the source node // prev[] -- the previous node of the ith node // c[][] -- every two nodes' distance void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum]) {int i,j;bool s[maxnum]; // 判斷是否已存入該點到S集合中for(i=1; i<=n; ++i){dist[i] = c[v][i];s[i] = 0; // 初始都未用過該點if(dist[i] == maxint)prev[i] = 0;elseprev[i] = v;}dist[v] = 0;s[v] = 1;// 依次將未放入S集合的結點中,取dist[]最小值的結點,放入結合S中// 一旦S包含了所有V中頂點,dist就記錄了從源點到所有其他頂點之間的最短路徑長度// 注意是從第二個節點開始,第一個為源點for(i=2; i<=n; ++i){int tmp = maxint;int u = v;// 找出當前未使用的點j的dist[j]最小值for(j=1; j<=n; ++j)if((!s[j]) && dist[j]<tmp){u = j; // u保存當前鄰接點中距離最小的點的號碼tmp = dist[j];}s[u] = 1; // 表示u點已存入S集合中// 更新distfor(j=1; j<=n; ++j)if((!s[j]) && c[u][j]<maxint){int newdist = dist[u] + c[u][j];if(newdist < dist[j]){dist[j] = newdist;prev[j] = u;}}} }// 查找從源點v到終點u的路徑,并輸出 void searchPath(int *prev,int v, int u) {int que[maxnum];int tot = 1;que[tot] = u;tot++;int tmp = prev[u];while(tmp != v){que[tot] = tmp;tot++;tmp = prev[tmp];}que[tot] = v;//輸出路徑for(int i=tot; i>=1; --i)if(i != 1)cout << que[i] << " -> ";elsecout << que[i] << endl; }int main() {int i,j; // freopen("input.txt", "r", stdin);// 各數組都從下標1開始// 輸入結點數 // cin >> n;// 輸入路徑數 // cin >> line;double x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;double p, q, len; // 輸入p, q兩點及其路徑長度// 初始化c[][]為maxintfor(int i=1;;i++){cin>>p[i].x>>p[i].y;}for(i=1; i<=n; ++i)for(j=1; j<=n; ++j)c[i][j] = maxint;for(i=1; i<=line; ++i){cin >> p >> q >> len;if(len < c[p][q]) // 有重邊{c[p][q] = len; // p指向qc[q][p] = len; // q指向p,這樣表示無向圖}}for(i=1; i<=n; ++i)dist[i] = maxint;//輸出矩陣-------for(i=1; i<=n; ++i){for(j=1; j<=n; ++j)printf("%8d", c[i][j]);printf("\n");}int begin,end;printf("輸入起點和終點\n");scanf("%d%d",&begin,&end);Dijkstra(end, begin, dist, prev, c);// 最短路徑長度cout << "點A到點B的最短路徑長度: " << dist[n] << endl;// 路徑cout << "點A到點B的路徑為: ";searchPath(prev, begin, end);return 0; } /* 測試數據: 4 4 1 2 1 2 3 1 3 4 1 1 4 4 2 2 cout<< 2 2->3->4 */

版權聲明:本文為博主原創文章,未經博主允許不得轉載。

posted on 2014-07-19 10:18 france 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/france/p/4808741.html

總結

以上是生活随笔為你收集整理的迪杰斯特拉--- 模板(求最短路径/输出路径/所有路径都可以走的做法)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。