最短路徑應用題

2021-07-25 22:50:49 字數 2821 閱讀 9751

在沙漠中有n個城邦國家(編號0~n-1),每天都有商隊從本國出發將本國商品運到其它各個國家,到達各個目的國家後又將該國的商品運回本國。在前往目的國家的路程中,商隊可能要需要從其它國家境內穿過。每穿過乙個國家商隊就需要獲得一張該國的通關卡,以便該商隊當天沿原路返回時使用。經過多年的摸索,每支商隊都已經掌握了國家間的最佳線路(距離最短的路徑,不計算在國家內穿過的距離)。

為了減少商隊的負擔,各國之間的商隊做了如下約定:每天兩國之間只由一國的商隊負責往返運輸,即:如果當天有a國的商隊從a國出發去往b國,到達b國後再返回a國,那麼當天就不會有b國的商隊去往a國。

特別的,在乙個國家境內穿過所需持有的通關卡每天都需要提前準備(因為要標明日期)。而兩個國家之間的最佳路徑(距離最短的路徑)可能有多條。雖然商隊只會選擇其中的一條,但是各條最佳路徑上需要經過的國家的管理者們並不知道商隊會選擇哪條路徑,因此他們都假設商隊當天會選擇自己在的這條路徑,都會提前準備通關卡(雖然這些通關卡最後可能並沒有用上)。

請計算各個國家每天需要提前準備多少張通關卡。

注意事項:

1. 商隊沿著某條最短路徑從a國去往b國時,只有沿途經過的國家才需要通關卡,起點a國和終點b國都不需要通關卡。

2. 兩國間的最短路徑可能有多條,根據題目假設,相當於每一條路徑都需要統計。

3. 每天兩國之間只會有一國的商隊往返,當天a國商隊去往b國的路程中會領取通關卡,但是從b國返回a國的路程中不需要再領取通關卡,因此不要重複計算。

4. 商隊當天是沿原路返回。

5. 商隊都足夠聰明不會沿著某條路轉一圈又回到了本國,也即乙個頂點到自身的距離為0,不存在從自身出發並指向自身的環形路徑。

示例:如下圖所示的有四個國家示意圖

國家0和1之間的最短路徑為:0 → 1,沒有經過除起點終點外的國家

國家0和2之間的最短路徑為:0 → 2,沒有經過除起點終點外的國家

國家0和3之間的最短路徑有兩條,分別為:0 → 1 → 3和0 → 2 → 3,分別經過國家1和國家2

國家1和2之間的最短路徑有兩條,分別為:1 → 2和1 → 0 → 2,其中第二條最短路徑經過國家0

國家1和3之間的最短路徑為:1 → 3,沒有經過除起點終點外的國家

國家2和3之間的最短路徑為:2 → 3,沒有經過除起點終點外的國家

所以最終各個國家需要準備的通關卡依次為:1,1,1,0。國家0需要準備1張,因為國家1和2之間的其中一條最短路徑經過它;國家1需要準備1張,因為國家0和3之間的其中一條最短路徑經過它;同理,國家2需要準備1張;國家3不需要準備(0張),因為沒有兩個國家間的最短路徑經過它。

第一行為乙個正整數n,表示國家的個數。國家的編號從0到n-1。n <= 400。

第二行為乙個正整數e,表示國家間聯通的道路。

接下來的e行,每行由三個整數組成(三個整數均在int型的表數範圍內),前兩個整數表示國家編號,第三個整數表示兩國家間路徑的距離,兩個整數之間用乙個空格分隔。如:1 2 6,表示國家1與國家2之間有路徑相連,長度為6。這e行之外的國家間認為沒有直接相連的路徑。

按照所需準備的通關卡數目從多到少的順序進行輸出,對於數目相同的國家按照編號順序(小到大)輸出。 每行輸出兩個整數,分別為國家編號和該國需要準備的通關卡,兩個整數之間用乙個空格分隔,每一行尾有換行符,最後一行也要有換行符。有幾個國家就輸出幾行。

4 5

0 1 1

0 2 1

1 2 2

1 3 4

2 3 4

0 1

1 1

2 1

3 0和傳統floyd演算法區別在於用i->k+k->j更新i->j時,k要用乙個陣列儲存下來。重點在於判斷乙個點是不是在某條最短路徑上。

#include

#include

using namespace std;

struct graph;

struct output;

void initgraph(graph &g,int n)

void insert(graph &g,int start,int end,int w,int

*&path_num)

}void floyd(graph &g,int

*&path_num)

for(int i=0;ifor(int

s=0;s

s++)

for(int e=s+1;eif(g.w[s

*g.v+e]>g.w[s

*g.v+i]+g.w[i*g.v+e])

else

if(g.w[s

*g.v+e]==g.w[s

*g.v+i]+g.w[i*g.v+e]

&& i!=s && i!=e)

}}void count(graph &g,int

s,int e,output *&card,int

*&path_num)

}bool cmp(output x,output y)

int main()

output *card=new output[n];

for(int i=0;i0;

}floyd(g,path_num);

for(int

s=0;s

1;s++)

for(int e=s+1;es,e,card,path_num);

sort(card,card+n,cmp);

for(int i=0;i" "

delete path_num;

delete g.w;

return

0;}

P1144 最短路計數 題解 最短路應用題

其實這道題目是最短路的變形題,因為資料範圍 n le 10 6,m le 2 times 10 6 所以直接用dijkstra演算法是不行的,可以使用 dijkstra 堆優化 或者 spfa演算法來實現。我這裡使用 spfa演算法 來實現 不會dijkstra堆優化囧 這道題目因為需要計數,所以需...

演算法題 最短路徑 03 最短路

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

Codeup最短路徑 最短路徑

n個城市,標號從0到n 1,m條道路,第k條道路 k從0開始 的長度為2 k,求編號為0的城市到其他城市的最短距離。第一行兩個正整數n 2 n 100 m m 500 表示有n個城市,m條道路,接下來m行兩個整數,表示相連的兩個城市的編號。n 1行,表示0號城市到其他城市的最短路,如果無法到達,輸出...