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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【数据机构】最短路径之Dijkstra算法(迪克斯特拉算法)

發(fā)布時間:2024/3/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【数据机构】最短路径之Dijkstra算法(迪克斯特拉算法) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

最短路徑問題是圖論中的一個經(jīng)典問題。

最短路徑問題就是求圖G(V,E)中某兩個特定頂點間最短的路徑長度。

本文介紹求最短路徑的一個經(jīng)典算法——Dijkstra算法,

它由荷蘭圖靈獎獲得者、計算機科學(xué)家Dijkstra于1959年提出。

該算法能夠有效地計算出某個特定頂點(稱為源點),到其余所有頂點的最短路徑,

即它能夠很好地解決單源最短路徑問題。

?


1. 問題介紹

1.1 題目描述

從一個城鎮(zhèn)抵達另一個城鎮(zhèn)時,有不同的路徑可以選擇,請幫助行人選擇最短路徑。 現(xiàn)在,已知起點和終點,請計算出要從起點到終點,最短需要行走多少距離。

1.2 輸入

本題包含多組數(shù)據(jù)。 每組數(shù)據(jù)第一行包含兩個正整數(shù)N和M(0<N<200,0<M<1000),分別代表現(xiàn)有城鎮(zhèn)的規(guī)模和已修建的道路的數(shù)目。城鎮(zhèn)分別以0~N-1編號。 接下來是M行道路信息,每一行有三個整數(shù)A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城鎮(zhèn)A和城鎮(zhèn)B之間有一條長度為X的雙向道路。 再接下來的下一行有兩個整數(shù)S,T(0<=S,T<N),分別代表起點和終點。

1.3 輸出

對于每組數(shù)據(jù),請在一行中輸出最短需要行走的距離。 若不存在從S到T的路線,則輸出-1。

1.4 樣例輸入

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

1.5 樣例輸出

2 -1

?


2. 解決方案

我們不作證明的給出以下結(jié)論:

  • 最短路徑的特點
    • 源點到該點相鄰(只含一條弧),該弧的權(quán)值最小;
    • 若已知源點到目標點的最短路徑,則源點到達該路徑中其他結(jié)點的路徑,也是最短路徑。
      ?

下面給出Dijkstra算法:

  • Dijkstra算法在運行過程中將頂點集合V分成兩個集合S和T。
    • ?S:已確定的頂點集合,初始只含源點s
    • ?T=V-S:尚未確定的頂點集合
    • 算法反復(fù)從集合T中選擇當(dāng)前到源點s最近的頂點u,將u加入集合S,然后對所有從u發(fā)出的邊進行松弛操作。

?


3. 代碼

又到了重要的代碼環(huán)節(jié)。。上干貨

//注意該代碼是無向圖 //如果是有向圖,在初始化圖的時候只保留from->to 即可#include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<queue> #include<climits>using namespace std;const int MAXN = 200; const int INF = INT_MAX;struct Edge {int to;int length;Edge(int t, int l) :to(t), length(l) {} };struct Point {int number;int distance;Point(int n, int d) :number(n), distance(d) {}friend bool operator < (Point a, Point b){return a.distance > b.distance;} };vector<Edge> graph[MAXN]; int dis[MAXN]; bool visit[MAXN];void Dijkstra(int s) {priority_queue<Point> myPriorityQueue;dis[s] = 0;myPriorityQueue.push(Point(s, dis[s]));while (!myPriorityQueue.empty()){int u = myPriorityQueue.top().number;myPriorityQueue.pop();visit[u] = true;for (int i = 0; i < graph[u].size(); i++){int v = graph[u][i].to;int d = graph[u][i].length;if (!visit[v] && dis[v] > dis[u] + d){dis[v] = dis[u] + d;myPriorityQueue.push(Point(v, dis[v]));}}}return; }int main() {int n, m;while (scanf("%d%d", &n, &m) != EOF){memset(visit, false, sizeof(visit));memset(graph, 0, sizeof(graph));fill(dis, dis + n, INF);while (m--){int from, to, length;scanf("%d%d%d", &from, &to, &length);graph[from].push_back(Edge(to, length));graph[to].push_back(Edge(from, length));}int s, t;scanf("%d%d", &s, &t);Dijkstra(s);if (dis[t] == INF){dis[t] = -1;}printf("%d\n", dis[t]);}return 0; }

?


4. 總結(jié)

注意一下,上面的代碼處理的是無向圖的最短路徑問題。

考慮一下,如果是有向圖的最短路徑問題如何解決呢?

事實上,只需要簡單改變graph的構(gòu)造方式即可,即注釋掉

graph[to].push_back(Edge(from, length));

之后,本代碼可解決有向圖的最短路徑問題。

?


圖論這個章節(jié)難度還是挺大的,筆者看了挺長時間還是不得要領(lǐng)。。

在返校之前盡量把最小生成樹問題也放上來吧。。

?

總結(jié)

以上是生活随笔為你收集整理的【数据机构】最短路径之Dijkstra算法(迪克斯特拉算法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。