1488 最短距離(單源點最短路問題)

2021-10-06 21:23:04 字數 1930 閱讀 4841

有 n 個村莊,編號 1 到 n。

村莊之間有 m 條無向道路,第 i 條道路連線村莊 ai 和村莊 bi,長度是 ci。

所有村莊都是連通的。

共有 k 個村莊有商店,第 j 個有商店的村莊編號是 xj。

然後給出 q 個詢問,第 k 個詢問給出乙個村莊的編號 yk,問該村莊距離最近的商店有多遠?

輸入格式

第一行包含兩個整數 n,m。

接下來 m 行,每行包含三個整數 ai,bi,ci,表示第 i 條道路連線村莊 ai 和村莊 bi,長度是 ci。

再一行包含整數 k。

接下來 k 行,每行包含乙個整數 xj,表示第 j 個有商店的村莊編號是 xj。

再一行包含整數 q。

接下來 q 行,每行包含乙個整數 yk,表示詢問編號為 yk 的村莊與其距離最近的商店之間的距離。

輸出格式

對於每個詢問,輸出該詢問的結果。

資料範圍

2≤n≤105,

n−1≤m≤min( n(n

−1)2

\frac

2n(n−1

)​,105),

1≤q≤105,

1≤k≤n,

1≤ci≤10000

輸入樣例:

7 7

1 2 5

1 4 3

2 3 2

2 5 1

3 6 7

5 6 8

6 7 637

5471

2345

67

輸出樣例:

313

0060

如果每一次都從詢問的村莊出發,去求該村莊與其距離最近的商店之間的距離的話時間複雜度會大大提公升。從而導致超時。這時可以使用逆向思維解決該問題,即建立乙個超級源點,新增超級源點到各個商品之間的有向邊(紅色的邊),其權值為0,那個該問題就轉變成了求超級源點到各點的最短路徑問題。使用spfa演算法求即可。

圖1 ## **

#include

#include

#include

using

namespace std;

int n,m;

/*h陣列是鄰接表的頭它的下標是當前結點的編號,值是當前結點第一條邊的編號(其實是最後加入的那一條邊),

e陣列是邊的集合,它的下標是當前邊的編號,數值是當前邊的終點。ne是nextedge,如果ne是-1表示當前結點沒有下一條邊,

ne的下標是當前邊的編號,數值是當前結點的下一條邊的編號,idx記錄下乙個要分配的邊的編號,

如果還是不明白,先學習鏈式前向星後再看本文效果會更佳

*/int h[

100005

],e[

300005

],ne[

300005

],w[

300005

],idx;

int dist[

100005];

//dist[i]表示0號點走到i號點的最短距離

bool visit[

100005];

//visit[i]表示第i個結點是否在佇列中

void

add(

int u,

int v,

int p)

void

spfa()

}}}}

intmain()

cin>>m;

while

(m--

)spfa()

; cin>>m;

while

(m--

)return0;

}

最短距離及最短路(Floyd 演算法)

include include using namespace std define n 100 define max 1000000 int d n n int path n n void min d int h 該函式找出最短距離,及最短路徑 coutcoutint h,a,b,k cout 輸...

1407 最短距離

兩個點 a b 均在做勻速直線運動。給出 t 0時刻 a b 的座標,以及 a b 的速度,計算t 0時兩個點的距離的最小值。輸入的第一行包含乙個整數 t 1 t 200 表示一共有 t 組測試資料。對於每組測試資料,第一行包含4個整數 x a y a v ax v ay 103 x a y a v...

編輯最短距離

給定兩個字串s和t,對於t我們允許三種操作 1 在任意位置新增任意字元 2 刪除存在的任意字元 3 修改任意字元 問最少操作多少次可以把字串t變成s?例如 s abcf t dbfg 那麼我們可以 1 把d改為a 2 刪掉g 3 加入c 所以答案是3。1 把t中字元全刪了,再新增s的全部字元,操作次...