Rqnoj341星門跳躍

題目描述

在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.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章