最短路徑問題 演算法總集(待完善)

2021-09-13 16:55:11 字數 3478 閱讀 7298

某省自從實行了很多年的暢通工程計畫後,終於修建了很多路。不過路多了也不好,每次要從乙個城鎮到另乙個城鎮時,都有許多種道路方案可以選擇,而某些方案要比另一些方案行走的距離要短很多。這讓行人很困擾。

現在,已知起點和終點,請你計算出要從起點到終點,最短需要行走多少距離。

input

本題目包含多組資料,請處理到檔案結束。

每組資料第一行包含兩個正整數n和m(0output對於每組資料,請在一行裡輸出最短需要行走的距離。如果不存在從s到t的路線,就輸出-1.

sample input
3 3

0 1 1

0 2 3

1 2 1

0 23 1

0 1 1

1 2

sample output
2

-1

多源最短路徑演算法

佛洛依德演算法

基本思路:從i號頂點到j號頂點只經過前k號點的最短路程。時間複雜度o(n^2)**如下:

#include

#include

#include

#define inf 1000000

using namespace std;

int arr[

205]

[205];

intmain()

}for

(int i=

0;i)int x,y;

scanf

("%d%d"

,&x,

&y);

//弗洛伊德演算法核心**

for(

int k=

0;k}if

(arr[x]

[y]>=inf)cout<<-1

}

單源最短路徑演算法

迪傑斯特拉演算法

演算法的基本思想是:每次找到離源點(上面例子的源點就是1號頂點)最近的乙個頂點,然後以該頂點為中心進行擴充套件,最終得到源點到其餘所有點的最短路徑。時間複雜度o(n^2),**如下:

include

#include

#include

#include

#define inf 1000000

using namespace std;

int arr[

205]

[205];

int dis[

205]

;//表示起點到各個點的距離

bool vis[

205]

;//記錄這個頂點是否被選過

intmain()

}for

(int i=

0;i)int x,y,k;

scanf

("%d%d"

,&x,

&y);

//記錄起始起點到各個定點的距離

for(

int i=

0;i) vis[x]

=true;

//迪傑斯特拉演算法核心

for(

int i=

0;ivis[k]

=true;

for(

int i=

0;iprintf

("%d\n"

,dis[y]

>=inf?-1

:dis[y]);

}return0;

}

迪傑斯特拉+heap優化演算法:

我們首先定義乙個陣列d,代表我們選定的起點到其他各個點的距離最小值。

然後,將d陣列中除了起點以外的所有的元素都賦成inf(無限大)。

然後開始掃瞄起點所連線的點,找出乙個直接距離最短的點,加入已生成的樹中,並將連線它們的這條邊加入最小生成樹中。

然後繼續,從已有的最小生成樹中的所有點出發,找到乙個距離最近的,繼續加入生成樹

堆優化:

堆優化的主要思想就是使用乙個優先佇列(就是每次彈出的元素一定是整個佇列中最小的元素)來代替最近距離的查詢,

用鄰接表代替鄰接矩陣,這樣可以大幅度節約時間開銷。時間複雜度為o(nlogn).

鄰接矩陣寫法:

#include

#define inf 1000000

using namespace std;

typedef pair<

int,

int> p;

//first表示最短路 //second表示頂點的編號

int arr[

10005][

10005];

int dis[

10005];

bool vis[

10005];

intmain()

}//輸入

int a,b,c;

for(

int i=

0;i)int x,y;

scanf

("%d%d"

,&x,

&y);

//迪傑斯特拉+heap優化演算法核心

dis[x]=0

; priority_queue,greater> q;

//greater引數將first的值從小到大排序

q.push()

;while

(q.size()

));}

}}printf

("%d\n"

,dis[y]

>=inf?-1

:dis[y]);

}return0;

}

鄰接表寫法:
#include

#define inf 0x3f3f3f3f

#define maxn 10000

using namespace std;

typedef pair<

int,

int> p;

vectorarr[maxn+5]

;int dis[maxn+5]

;bool vis[maxn+5]

;int

main()

);arr[b]

.push_back()

;}int x,y;

scanf

("%d%d"

,&x,

&y);

dis[x]=0

;//迪傑斯特拉鄰接表核心

priority_queue,greater> q;

q.push()

;while

(q.size()

));}

}}printf

("%d\n"

,dis[y]

>=inf?-1

:dis[y]);

}return0;

}

最短路徑問題演算法

dijksatr演算法是典型最短路演算法,用於計算乙個節點到其他所有節點的最短路徑,主要特點是以起始點為中心向外層層擴充套件,直到拓展到終點為止。設g v,e 是乙個帶權有向圖,把圖中頂點集合v分成兩組,第一組為已求出最短路徑的頂點集合 用s表示,初始時s中只有乙個源點,以後每求得一條最短路徑 就將...

最短路徑演算法 最短路

在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input 輸入包括多組資料。每組資料第一行是兩個整數n m n 100,m 10000 n...

最短路 最短路徑問題

題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點直線的距離。現在的任務是找出從一點到另一點之間的最短路徑。input 共有n m 3行,其中 第一行為乙個整數n。第2行...