道路與航線(最短路 縮點 拓撲排序)

2021-10-10 09:47:06 字數 3058 閱讀 1122

題目描述

農夫約翰正在乙個新的銷售區域對他的牛奶銷售方案進行調查。

他想把牛奶送到t個城鎮,編號為1~t。

這些城鎮之間通過r條道路 (編號為1到r) 和p條航線 (編號為1到p) 連線。

每條道路 i 或者航線 i 連線城鎮ai到bi,花費為ci。

對於道路,0≤ci≤10,000;然而航線的花費很神奇,花費ci可能是負數(−10,000≤ci≤10,000)。

道路是雙向的,可以從ai到bi,也可以從bi到ai,花費都是ci。

然而航線與之不同,只可以從ai到bi。

事實上,由於最近恐怖主義太囂張,為了社會和諧,出台了一些政策:保證如果有一條航線可以從ai到bi,那麼保證不可能通過一些道路和航線從bi回到ai。

由於約翰的奶牛世界公認十分給力,他需要運送奶牛到每乙個城鎮。

他想找到從傳送中心城鎮s把奶牛送到每個城鎮的最便宜的方案。

輸入格式

第一行包含四個整數t,r,p,s。

接下來r行,每行包含三個整數(表示乙個道路)ai,bi,ci。

接下來p行,每行包含三個整數(表示一條航線)ai,bi,ci。

輸出格式

第1…t行:第i行輸出從s到達城鎮i的最小花費,如果不存在,則輸出「no path」。

資料範圍

1≤t≤25000,

1≤r,p≤50000,

1≤ai,bi,s≤t,

輸入樣例6 3 3 4

1 2 5

3 4 5

5 6 10

3 5 -100

4 6 -100

1 3 -10

輸出樣例

no path

no path50

-95-100

題目分析

看完這道題之後第乙個想到的應該是用spfa演算法來直接求最短路,但是這道題會卡spfa,因此我們需要考慮要如何用dijkstra演算法來解決這道題。

因為這道題目存在負權邊,因此我們不能直接用dijkstra演算法來解決這道題。因為題目保證:如果有一條航線可以從ai到bi,那麼保證不可能通過一些道路和航線從bi回到ai。因此說明航線之間是無環的且航線不可能和道路是重邊

因此,如果我們將所有的道路連通塊縮成乙個點,那麼這個圖就變成了乙個dag。此時我們就可以對這個圖進行拓撲排序了,然後再根據拓撲序進行遞推,最終就可以求出到達每個點的最短路徑。

(注:每個縮點內部的最短路我們可以直接用dijkstra算出)

這個題的思路相對來說不算太難,這道題的**實現也是乙個難點。

一下是yxc大佬給出的實現流程圖:

**如下

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define ull unsigned long long

#define pii pair

#define x first

#define y second

using

namespace std;

const

int n=

5e4+

5,inf=

0x3f3f3f3f

;int h[n]

,e[n*3]

,w[n*3]

,ne[n*3]

,idx;

int dist[n]

;bool st[n]

;int scc[n]

,in[n]

,cnt;

//scc 記錄每個點屬於那個連通塊,in統計入度,cnt 記錄連通塊數量

vector<

int> block[n]

;//記錄每個連通塊中含有那些點

queue<

int> q;

void

add(

int a,

int b,

int c)

//加邊函式

void

dfs(

int u,

int cnt)

}void

dijkstra

(int s));

//將該連通塊中的點全部放入堆中

while

(heap.

size()

));}

}}}void

topsort

(int s,

int n)

}int

main()

for(

int i=

1;i<=n;i++

)//dfs找出所有連通塊if(

!scc[i]

)dfs

(i,++cnt)

;while

(p--

)//輸入水路

topsort

(s,n)

;//求其拓撲序,並計算最短路

for(

int i=

1;i<=n;i++)if

(dist[i]

>inf/2)

puts

("no path");

else

printf

("%d\n"

,dist[i]);

return0;

}

bzoj 2200 道路與航線 最短路高階

time limit 10 sec memory limit 259 mb submit 528 solved 173 submit status discuss farmer john正在乙個新的銷售區域對他的牛奶銷售方案進行調查。他想把牛奶送到t個城鎮 1 t 25,000 編號為1t。這些城鎮...

bzoj 1179 縮點 最短路

題意 中文題面 解題思路 因為他能重複走且邊權都正的,那麼肯定乙個環的是必須走完的,所以先縮點,在重新建乙個圖跑最長路 include include include include include include includeusing namespace std const int inf 0...

POJ2762 tarjan縮點 拓撲排序

有向圖n 1000 m 6000,如果圖中任意兩點u,v 均有u可達v或v可達u,輸出yes,否則輸出no 嘛,強連通分量內的點肯定互相可達 對於縮點之後的dag,怎麼判呢?如果一開始就有多個入度為0的點,那麼就是no 交一發wa了 這時候就要想反例了 發現有一種情況也是no 比如1 2 1 3,2...