CodeVS 1269 匈牙利遊戲

2022-04-10 00:08:32 字數 2821 閱讀 5963

題目描述 description

歡迎來到匈牙利遊戲!布達佩斯(匈牙利首都)的街道形成了乙個彎曲的單向網路。

你被強制要求參加乙個賽跑作為乙個tv秀的一部分節目,比賽中你需要穿越這些街道,從s開始,到t結束。

很自然的,你想要盡快的完成比賽,因為你的比賽完成的越好,你就能得到更多的商業**合同。

但是,有乙個需要了解的是,如果有人過於聰明找到從s到t的最短路線,那麼他就被扔到國家極品人類保護系統中作為乙個國家寶藏收藏起來。你顯然要避免這種事情的發生,但是也想越快越好。寫乙個程式來計算乙個從s到t的嚴格次短路線吧。

有的時候,嚴格次短路線可能訪問某些節點不止一次。樣例2是乙個例子。

輸入描述 input description

第一行包含兩個整數n和m,n代表布達佩斯的節點個數,m代表邊的個數。節點編號從1到n。1代表出發點s,n代表終點t。接下來的m行每行三個整數a b l,代表有一條從a到b的長度為l的單向同路。你可以認為a不等於b,也不會有重複的(a,b)對。

輸出描述 output description

輸出從s到t的嚴格次短路的長度。如果從s到t的路少於2條,輸出-1。

樣例輸入 sample input

樣例輸入1:

4 61 2 5

1 3 5

2 3 1

2 4 5

3 4 5

1 4 13

樣例輸入2:

2 21 2 1

2 1 1

樣例輸出 sample output

樣例輸出1:

11樣例輸出2:

3資料範圍及提示 data size & hint

對於樣例1:

there are two shortest routes of length 10 (1 → 2 → 4,1 → 3 → 4) and the strictly-second- shortest route is 1 → 2 → 3 → 4 with length 11.

對於樣例2:

the shortest route is 1 → 2 of length 1, and the strictly-second route is 1 → 2 → 1 → 2 of length 3.

實際上就是求次短路,用spfa來解決。

維護兩個陣列,乙個儲存最短路,另乙個儲存次短路,一邊求最短路一邊求次短路。

每次更新最短路和次短路有3種情況:

1.當到x的最短路可以更新到y的最短路的時候,到y的次短路更新為原來到y的最短路,到y的最短路更新為到x的最短路加上xy的距離;

2.當到x的最短路不能更新到y的最短路,但可以更新到y的次短路,並且到x的最短路+xy的距離不等於到y的最短路(如果相等的話,那麼到y的次短路和最短路是一樣的,於是錯亂),則用更新到y的次短路;

3.當到x的最短路不能更新到y的最短路,也不能更新到y的次短路,但到x的次短路能更新到y的次短路,就更新它。

最後輸出到n的次短路就是答案。

**:

var q,ne,b,c:array[1..1000000] of longint;

var d1,d2,fir:array[1..100000] of int64;

var us:array[1..100000] of boolean;

var n,m,i,tot,x,y,z:longint;

procedure add(x,y,z:longint); begin inc(tot);b[tot]:=y;c[tot]:=z;ne[tot]:=fir[x];fir[x]:=tot; end;//鄰接表

procedure spfa(s:longint);//最短路與次短路

var i,j,u,h,w,t,v:longint;

begin

d1[s]:=0;us[s]:=true;h:=1;t:=1;q[1]:=s;

while h<=t do

begin

u:=q[h];j:=fir[u];

while j>0 do

begin

v:=b[j];w:=c[j];

if d1[v]>d1[u]+w then

begin

d2[v]:=d1[v];d1[v]:=d1[u]+w;

if not us[v] then begin inc(t);q[t]:=v;us[v]:=true; end;

end else

if (d1[u]+w<>d1[v])and(d2[v]>d1[u]+w) then

begin

d2[v]:=d1[u]+w;

if not us[v] then begin inc(t);q[t]:=v;us[v]:=true; end;

end else

if d2[v]>d2[u]+w then

begin

d2[v]:=d2[u]+w;

if not us[v] then begin inc(t);q[t]:=v;us[v]:=true; end;

end;

j:=ne[j];

end;

inc(h);us[u]:=false;

end;

end;

begin

readln(n,m);

for i:=1 to m do begin readln(x,y,z);add(x,y,z); end;

for i:=1 to n do begin d1[i]:=maxlongint;d2[i]:=maxlongint; end;

spfa(1);

if d2[n]=maxlongint then writeln(-1) else writeln(d2[n]);

end.

codevs 1269 匈牙利遊戲

qaq 求次短路分三種情況討論 1 最短能更新最短 2 次短能更新次短 3 最短能更新次短並且次短不能更新最短 什麼叫不能更新最短了呢 就是更新完了和最短一樣長的 恩恩 就是這樣 include include include include include using namespace std ...

codevs 1269 匈牙利遊戲

codevs 1269 匈牙利遊戲 題目大意 求次短路 資料範圍 2 n 20000,1 m 100000,1 l 10000 思路 spfa的時候在更新最短路的時候順便更新一下次短路就好了。題解 include include include include using namespace std...

codevs 1269 匈牙利遊戲

暴力 亂搞 55分 似乎只有暴力得分了 include include include include include define maxn 1000010 using namespace std intn,m,num,head maxn dfn maxn low maxn s maxn top,...