CSU 1808 地鐵 最短路變形

2022-06-26 03:45:16 字數 2979 閱讀 4310

time limit: 5000 ms memory limit: 131072 kb

bobo 居住在大城市 icpccamp。

icpccamp 有 n 個地鐵站,用 1,2,…,n 編號。 m 段雙向的地鐵線路連線 n 個地鐵站,其中第 i 段地鐵屬於 c i 號線,位於站 a i,b i 之間,往返均需要花費 t i 分鐘(即從 a i 到 b i需要 t i 分鐘,從 b i 到 a i 也需要 t i 分鐘)。

眾所周知,換乘線路很麻煩。如果乘坐第 i 段地鐵來到地鐵站 s,又乘坐第 j 段地鐵離開地鐵站 s,那麼需要額外花費 |c i-c j | 分鐘。注意,換乘只能在地鐵站內進行。

bobo 想知道從地鐵站 1 到地鐵站 n 所需要花費的最小時間。

input

輸入包含不超過 20 組資料。

每組資料的第一行包含兩個整數 n,m (2≤n≤10 5,1≤m≤10 5).

接下來 m 行的第 i 行包含四個整數 a i,b i,c i,t i (1≤a i,b i,c i≤n,1≤t i≤10 9).

保證存在從地鐵站 1 到 n 的地鐵線路(不一定直達)。

output

對於每組資料,輸出乙個整數表示要求的值。

sample input

3 3

1 2 1 1

2 3 2 1

1 3 1 1

3 31 2 1 1

2 3 2 1

1 3 1 10

3 21 2 1 1

2 3 1 1

sample output

1

32

題解:

如果只記錄到某個節點x的最短路長度d[x],並且記錄對應於d[x],是坐哪號線來到節點x的,這樣顯然是錯誤的。

原因比如這樣的樣例:

3 31 2 1 2

1 2 3 3

2 3 3 5

可以看出,d[x]要擴充套件到d[x][c],即這題的狀態有兩個量決定:到了節點x,最後乘坐的是c號線;

那麼,如果我們把節點x用若干條邊edge(u1→x)…edge(uk→x)來代替,那麼我們就相當於把d[x]要擴充套件到d[x][c]了;

所以我們可以直接把邊當成點,對邊做最短路。

(這題對邊做最短路,如果用spfa的話會tle,要使用堆優化dijkstra)

3'>3

'>1

'>2

'>1

'>2

'>1

'>2

'>3

'>3

'>2

'>3

'>3

'>5

'>ac**:

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;typedef pair

int>pair;

const ll inf=1e18;

const

int maxn=1e5+10

;const

int maxm=2e5+10; //

無向邊拆成兩條有向邊

intn,m;

struct

edge;

edge e[maxm];

inthead[maxn],ne;

void

init()

void addedge(int u,int v,int

c,ll t)

ll ans;

ll d[maxm];

bool

vis[maxm];

void dijkstra(int

st)

while(!q.empty())}}

}int

main()

dijkstra(1);

printf(

"%lld\n

",ans);

}}

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;typedef pair

int>pair;

const ll inf=1e18;

const

int maxn=1e5+10

;const

int maxm=2e5+10; //

無向邊拆成兩條有向邊

intn,m;

struct

edge;

vector

e;vector

g[maxn];

void init(int l,int

r)void addedge(int u,int v,int

c,ll t)

); g[u].push_back(e.size()-1);}

ll ans;

ll d[maxm];

bool

vis[maxm];

void dijkstra(int

st)

while(!q.empty())}}

}int

main()

dijkstra(1);

printf(

"%lld\n

",ans);

}}

注:兩份**的區別是分別用鏈式前向星和vector鄰接表存圖。

CSU 1808 地鐵 最短路變形

題意 icpccamp 有 n 個地鐵站,用 1,2,n 編號。m 段雙向的地鐵線路連線 n 個地鐵站,其中第 i 段地鐵屬於 ci 號 線,位於站 ai,bi 之間,往返均需要花費 ti 分鐘 即從 ai 到 bi 需要 ti 分鐘,從 bi 到 ai 也需要 ti 分鐘 眾所周知,換乘線路很麻煩...

CSU 1808 地鐵(最短路)

題意 n個地鐵站,m條線路,地鐵站之間花費t時間,不屬於同一條線路的地鐵站需要 轉站 即加上乙個額外花費w w為線路代號的差值 求1到n的最短時間 思路 由於有轉站的影響,可以考慮將地鐵站拆點,權值是他們的差值,或者直接以邊作為點也是可以的 includeusing namespace std co...

CSU1808 地鐵 dijkstra變形

題解 由於中轉線路需要花費一定的時間,所以一般的以頂點為研究物件的dijkstra演算法就不適用了,因為在鬆弛過程中,當前節點的最短路徑不能知道是從那條線路過來的。儲存當前結點的上一站是從那條線路過來?看似可以,但是站與站之間的線路又怎麼儲存。矩陣?100000 100000 記憶體不足。領接表?不...