L2 001 緊急救援(dijkstra演算法

2022-08-27 04:51:11 字數 3443 閱讀 6888

作為乙個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連線城市的快速道路。每個城市的救援隊數量和每一條連線兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助**給你的時候,你的任務是帶領你的救援隊盡快趕往事發地,同時,一路上召集盡可能多的救援隊。

輸入第一行給出4個正整數n、m、s、d,其中n(2≤n≤500)是城市的個數,順便假設城市的編號為0 ~ (n−1);m是快速道路的條數;s是出發地的城市編號;d是目的地的城市編號。

第二行給出n個正整數,其中第i個數是第i個城市的救援隊的數目,數字間以空格分隔。隨後的m行中,每行給出一條快速道路的資訊,分別是:城市1、城市2、快速道路的長度,中間用空格分開,數字均為整數且不超過500。輸入保證救援可行且最優解唯一。

第一行輸出最短路徑的條數和能夠召集的最多的救援隊數量。第二行輸出從s到d的路徑中經過的城市編號。數字間以空格分隔,輸出結尾不能有多餘空格。

4 5 0 3

20 30 40 10

0 1 1

1 3 2

0 3 3

0 2 2

2 3 2

2 60

0 1 3

dijkstra演算法是貪心演算法在求解路徑問題上的應用。

作用:dijkstra演算法能夠解決邊權非負的加權有向圖的單起點最短路徑問題。也就是說,規定乙個起點,就能夠得到這個加權有向圖中其他點距該起點的最短距離。

資料結構:陣列known[ ]用於標記這些點的狀態(已知、未知); 陣列dis[ ],也就是下表中的dv,表示每個點到起點的距離,附初值時,除了起點自身,其他的點到起點的距離都設為無窮,在實際程式設計時,可用定義乙個很大的數(比如99999999)作為常量為其賦值;陣列pre[ ],也就是下表中的pv,表示引起dv變化的最後乙個頂點,也就是以這種路徑到達這個點經過的前乙個點。

演算法:以下面這個加權有向圖為例,並假設開始結點為v1。初始配置如圖9-12所示。每次更新下圖的**,演算法都會選擇未知的點中dv最小的乙個標記為已知,然後去尋找這個點的下幾個鄰接點,如果該鄰接點到這個已知點的距離加上這個已知點的dv小於該鄰接點的dv,那麼更新dv和pv,這其實就是從這個已知點這裡走會更近的意思;如果該鄰接點是已知的就跳過(因為每一次都是先將dv最小的點標記為已知,所以該點的dv不會更小)。

過程如圖:

下表是每次更新的**。在下面我直接把書上的講解搬上來,書是《資料結構與演算法分析:c語言描述》。

了解了dijkstra 以後,再來看這道題,發現題目就是在這個演算法的基礎上加了乙個「救援隊」和經過的結點數。那麼我們在**後多加兩列就ok了,也就是在程式中加兩個陣列。最後按順序輸出路徑那裡使用了遞迴,具體見**。

1、fill()可以按照單元賦值,將乙個區間的元素都賦同乙個值,它在標頭檔案裡面。

它可以賦值任何,比如int陣列:fill(arr, arr + n, 要填入的內容); 比如vector:fill(v.begin(), v.end(), 要填入的內容);比如二維陣列fill(f[0], f[0]+n*n, 要填入的內容);

【c++】fill函式,fill與memset函式的區別

第一次寫dijkstra,一些陣列的命名感覺不是那麼合適,將就看吧。

#include #include 

using

namespace

std;

const

int inf=99999999

;int v,e,a,b;//

點、邊、起點、終點

int pv[505];//

路徑中每個點的前乙個點

void printpath(int v)//

遞迴輸出路線

printpath(pv[v]);

printf("%d

", v);

}int

main()

intf,t,l;

int dis[v][v];//

邊權 fill(dis[0],dis[0]+v*v,inf);

for(int i=0;i)

int known[v]=;//

最初所有的點都為未知

intdv[v];

fill(dv,dv+v,inf);//

所有點到起點的距離除了起點自身是0,其餘都是無窮

dv[a]=0

;

intmin;

intminn;

int num[v];//

累加的救援隊的數量

//num[a]=help[a];

fill(num,num+v,help[a]);

int way[v]=;//

從出發點到v結點擁有的最短路徑的條數

for(int i=0;i//

dijkstra

} if(minn==-1)//

如果剩下未知的點全是dv=inf,break

break

; known[minn]=1

;

for(int k=0;k//

找該點鄰接的下乙個頂點,並求其dv

else

if(dis[minn][k]+min==dv[k])

} } }}

cout

"printpath(b);

return0;

}

殺不死我的使我更強大 _(:з」∠)_

L2 001 緊急救援

這道題就是一道最短路 dijkstra演算法 將模板稍作修改就行了,就是再另外加乙個記錄路線條數的陣列 即當路的長度與下乙個需要判斷的 節點的長度相等時路線就相加 和乙個記錄每個節點在最短路基礎上的車的總數量的陣列,然後就ok了,如下 include include include define m...

L2 001 緊急救援

作為乙個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連線城市的快速道路。每個城市的救援隊數量和每一條連線兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助 給你的時候,你的任務是帶領你的救援隊盡快趕往事發地,同時,一路上召集盡可能多的救援隊。輸入格式 ...

L2 001 緊急救援

l2 001.緊急救援 作為乙個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連線城市的快速道路。每個城市的救援隊數量和每一條連線兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助 給你的時候,你的任務是帶領你的救援隊盡快趕往事發地,同時,一路上召集盡可...