题目描述
在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.