最短路径(Dijkstra算法)(c/c++)
Dijkstra是一種求單源點(diǎn)最短路徑的算法,即求某一個(gè)頂點(diǎn)到其余各頂點(diǎn)之間的最短路徑,下面采用鄰接矩陣來存儲(chǔ)圖中信息
算法思路為:
1,假設(shè)v0是源點(diǎn),s是已求得最短路徑的終點(diǎn)集合,用D[i]來保存從v0到vi頂點(diǎn)之間的最短路徑。初始:將v0置于集合s之中,
2,初始化D[i]為v0到vi之間的權(quán)值。a,求從v0出發(fā)長(zhǎng)度最短的路徑,通過計(jì)算D[j]=min{D[i]|vi不屬于s},找到j(luò)頂點(diǎn),將j頂點(diǎn)加入s集合。b,求下一條最短路徑,因?yàn)橛行碌慕Y(jié)點(diǎn)加入到s集合中,所以需要修改從v0到其余不屬于s的頂點(diǎn)之間的D[i]上的值。即若D[j]+arcs[j][k]<D[k](k不屬于s中),修改D[k]值為D[j]+arcs[j][k]
3,重復(fù)2中的a,b步驟
示例如下
按照上面思路列出每一次循環(huán)的結(jié)果列表如下:
| v1 | ∞ | ∞ | ∞ | ∞ | ∞ |
| v2 | 10 (v0,v2) | \ | \ | \ | \ |
| v3 | ∞ | 60 (v0,v2,v3) | 50 (v0,v4,v3) | \ | \ |
| v4 | 30 (v0,v4) | 30 (v0,v4) | \ | \ | \ |
| v5 | 100 (vo,v5) | 100 (vo,v5) | 90 (v0,v4,v5) | 60 (vo,v4,v3,v5 | \ |
| vj | v2 | v4 | v3 | v5 | \ |
| s | {vo,v2} | {vo,v2,v4} | {vo,v2,v4,v3} | {vo,v2,v4,v3,v5} | ∞ |
輔助結(jié)構(gòu)
bool final[maxSize];//表示集合s final[i] = true;//頂點(diǎn)i在s中 final[i] = false;//i不在s中 bool p[maxSize][maxSize];//表示路徑, p[v][w] = true;//表示w頂點(diǎn)屬于從源點(diǎn)到v頂點(diǎn)最短路徑上的一個(gè)頂點(diǎn) p[v][w] = false;//表示w頂點(diǎn)不屬于從源點(diǎn)到v頂點(diǎn)最短路徑上的一個(gè)頂點(diǎn) int D[maxSize];//表示從源點(diǎn)到各個(gè)頂點(diǎn)之間最短路徑長(zhǎng)度Dijkstra算法
void dijkstra(mGraph& G, int v0) {int i, j, minValue, min;//初始化for (i = 0; i < G.vexnum; ++i){final[i] = false;D[i] = G.arc[v0][i];for (j = 0; j < G.vexnum; ++j)p[v0][j] = false;if (G.arc[v0][i] < infini){p[i][v0] = true;p[i][i] = true;}}final[v0] = true;//v0入集合D[v0] = 0;for (i = 1; i < G.vexnum; ++i)//循環(huán)G.vexnum-1次{//找到最小的D[i]minValue = infini;for (j = 0; j < G.vexnum; ++j){if (final[j]==false)if (minValue>D[j]){minValue = D[j];min = j;}}final[min] = true;//更新for (j = 0; j < G.vexnum; ++j){if (final[j] == false && minValue + G.arc[min][j] < D[j])//若G.arc[min][j]為INT_MAX,左邊相加則會(huì)溢出,所以不能使用INT_MAX{//更新DD[j] = minValue + G.arc[min][j];//更新pfor (int temp = 0; temp < G.vexnum; ++temp)p[j][temp] = p[min][temp];p[j][j] = true;}}} }完整示例
#include<iostream> #define infini INT_MAX/2//最大值不選取INT_MAX,防止溢出 #define maxSize 6//頂點(diǎn)數(shù)目 #define MAX 8//邊的個(gè)數(shù) //鄰接矩陣 typedef struct {int vexnum, arcnum;//頂點(diǎn)數(shù)和邊數(shù)char vex[maxSize];//頂點(diǎn)信息(字符)int arc[maxSize][maxSize];//二維數(shù)組(存儲(chǔ)邊上的信息) }mGraph;bool final[maxSize];//表示集合s bool p[maxSize][maxSize];//表示路徑 int D[maxSize];//表示從源點(diǎn)到各個(gè)頂點(diǎn)之間最短路徑長(zhǎng)度void dijkstra(mGraph& G, int v0);//求最短路徑 int main() {using namespace std;mGraph G;//鄰接矩陣存儲(chǔ)圖并進(jìn)行初始化G.vexnum = maxSize;G.arcnum = MAX;char vexData[maxSize] = { 'a', 'b', 'c', 'd', 'e','f' };//頂點(diǎn)信息int arcData[MAX][3] = { { 0, 2 ,10}, { 0, 5,100 }, { 0, 4 ,30}, { 1, 2,5 }, { 2, 3 ,50},{ 3, 5, 10 }, { 4, 3, 20 }, { 4, 5, 60 } };//連接的邊int i, j;for (i = 0; i < G.vexnum; ++i){G.vex[i] = vexData[i];for (j = 0; j < G.vexnum; j++)G.arc[i][j] = infini;}for (i = 0; i < G.arcnum; i++)G.arc[arcData[i][0]][arcData[i][1]] = arcData[i][2];//初始化完畢cout << "求從v0頂點(diǎn)出發(fā)的最短路徑: ";cout << endl;dijkstra(G, 0);for (i = 1; i < G.vexnum; ++i){if (D[i] == infini){cout << "不存在到v" << i<< "的路徑" << endl;continue;}cout << "到v" << i << ": 長(zhǎng)度為" << D[i] << ' '<< "最短路徑上的頂點(diǎn)為";for (j = 0; j < G.vexnum; ++j)if (p[i][j] == true)cout << 'v' << j << ' ';cout << endl;}cout << endl;return 0; } void dijkstra(mGraph& G, int v0) {int i, j, minValue, min;//初始化for (i = 0; i < G.vexnum; ++i){final[i] = false;D[i] = G.arc[v0][i];for (j = 0; j < G.vexnum; ++j)p[v0][j] = false;if (G.arc[v0][i] < infini){p[i][v0] = true;p[i][i] = true;}}final[v0] = true;//v0入集合D[v0] = 0;for (i = 1; i < G.vexnum; ++i)//循環(huán)G.vexnum-1次{//找到最小的D[i]minValue = infini;for (j = 0; j < G.vexnum; ++j){if (final[j]==false)if (minValue>D[j]){minValue = D[j];min = j;}}final[min] = true;//更新for (j = 0; j < G.vexnum; ++j){if (final[j] == false && minValue + G.arc[min][j] < D[j])//若G.arc[min][j]為INT_MAX,左邊相加則會(huì)溢出,所以不能使用INT_MAX{//更新DD[j] = minValue + G.arc[min][j];//更新pfor (int temp = 0; temp < G.vexnum; ++temp)p[j][temp] = p[min][temp];p[j][j] = true;}}} }輸出結(jié)果為下圖:
Floyd算法求最短路徑:
https://blog.csdn.net/Little_ant_/article/details/104293812
附:如果采用上面鏈接博文中的Floyd算法求上圖的最短路徑,結(jié)果如下:
(ps:希望大家可以多多點(diǎn)贊👍)
總結(jié)
以上是生活随笔為你收集整理的最短路径(Dijkstra算法)(c/c++)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AOE网(求关键路径)(c/c++)
- 下一篇: 最短路径(Floyd算法)(c/c++)