題目描述
在EVE遊戲中,宇宙被劃分成爲許多區域,每個區域中都有數目不定的星門,可以通過星門來跳躍到特定的區域(星門是雙向的)。
現在你正參與BBE聯軍與MLGBD聯盟的會戰,但由於飛船受損,需要盡快回到後方的友軍空間站進行維護。
試編寫程序,計算出所須的最短的返回空間站時間。
爲了簡化問題,我們約定飛船所在的位置爲區域1,空間站所在的位置爲區域N。
問題規模:
對於80%的數據,1<N<=10000,1<M<50000;
對於100%的數據,1<N<=30000,1<M<150000,1<=X[],Y[]<=N,1<=Z[]<=4096;
輸入格式
第1行,兩個整數N,M,分別爲區域的總數和星門的總數;
第2..M+1行,每行三個整數X[i],Y[i],Z[i],分別爲星門連接的兩個區域,以及跳躍所需時間;
輸出格式
一個整數,返回空間站所需的最短時間。
====================================================================================做的時候以爲是道模板題,理論上spfa是O(KE)可以A掉的,但貌似我寫的棧式Spfa被這個數據卡住了,只好穩妥一點,寫個堆優化的dijkstra,O(nlogn+E),瞬間A掉~
====================================================================================
這個Heap-Dijkstra以後可以當模板使~
貼代碼:
type hnode=record id,f:longint; end;
link=^node; node=record x,len:longint; next:link; end;
var heap:array[1..30000] of hnode; size:longint;
wh:array[1..30000] of longint;
g:array[1..30000] of link;
n,m,i,a,b,c:longint;
procedure conn(i,j,dis:longint);
var p:link;
begin
new(p);
p^.x:=j;
p^.len:=dis;
p^.next:=g[i];
g[i]:=p;
end;
procedure swap(i,j:longint);
var tmp:hnode;
begin
tmp:=heap[i];
heap[i]:=heap[j];
heap[j]:=tmp;
wh[heap[i].id]:=i;
wh[heap[j].id]:=j;
end;
procedure up(i:longint);
var j:longint;
begin
j:=i shr 1;
if j>0 then
if heap[i].f<heap[j].f then begin
swap(i,j);
up(j);
end;
end;
procedure down(i:longint);
var j:longint;
begin
j:=i shl 1;
if j<=size then begin
if j<size then
if heap[j+1].f<heap[j].f then
inc(j);
if heap[j].f<heap[i].f then begin
swap(i,j);
down(j);
end;
end;
end;
procedure insert(id,f:longint);
begin
inc(size);
heap[size].id:=id;
heap[size].f:=f;
wh[id]:=size;
up(size);
end;
procedure pop(var id,dis:longint);
begin
id:=heap[1].id;
dis:=heap[1].f;
swap(1,size);
dec(size);
wh[id]:=0;
down(1);
end;
function dijkstra:longint;
var i,j,x,dis:longint; p:link;
begin
size:=0;
insert(1,0);
for i:=2 to n do insert(i,maxlongint);
for i:=1 to n do begin
//for j:=1 to size do write('[',heap[j].id,#32,heap[j].f,']'); writeln;
pop(x,dis);
if x=n then exit(dis);
p:=g[x];
while p<>nil do begin
if wh[p^.x]<>0 then
if dis+p^.len<heap[wh[p^.x]].f then begin
heap[wh[p^.x]].f:=dis+p^.len;
up(wh[p^.x]);
end;
p:=p^.next;
end;
end;
exit(maxlongint);
end;
begin
assign(input,'rq341.in'); reset(input);
assign(output,'rq341.out'); rewrite(output);
readln(n,m);
for i:=1 to m do begin
readln(a,b,c);
conn(a,b,c);
conn(b,a,c);
end;
write(dijkstra);
close(input); close(output);
end.