NOI2010 海拔

又是一道平面图的题,有向边的处理要注意一下,向右的向上连,向下的向右连,向左的向下连,向上的向左连,然后转化即可,对于向上,左的,边界处的边没有必要连,最后还得用dijkstra,反正我的spfa超时2个点,不知道它牛怎么过的,只好打堆了...

View Code
  1 program noi2010(input,output);
  2 type
  3    node    = ^link;
  4    link    = record
  5          goal,w : longint;
  6          next   : node;
  7       end;
  8 var
  9    l           : array[0..251000] of node;
 10    d           : array[0..251000] of int64;
 11    v           : array[0..251000] of boolean;
 12    heap,pos    : array[0..251000] of longint;
 13    number      : array[0..501,0..501] of longint;
 14    final,start : longint;
 15    n,tot       : longint;
 16 procedure add(xx,yy,ww: longint );
 17 var
 18    tt : node;
 19 begin
 20    new(tt);
 21    tt^.goal:=yy;
 22    tt^.w:=ww;
 23    tt^.next:=l[xx];
 24    l[xx]:=tt;
 25 end; { add }
 26 procedure init;
 27 var
 28    i,j : longint;
 29    sum : longint;
 30 begin
 31    readln(n);
 32    start:=0;
 33    final:=n*n+1;
 34    sum:=0;
 35    for i:=0 to n*n+1 do
 36       l[i]:=nil;
 37    for i:=1 to n do
 38       for j:=1 to n do
 39       begin
 40      inc(sum);
 41      number[i,j]:=sum;
 42       end;
 43 end; { init }
 44 procedure make_graph();
 45 var
 46    i,j,ww : longint;
 47 begin
 48    for i:=1 to n+1 do
 49       for j:=1 to n do
 50       begin
 51      readln(ww);
 52      if i=1 then
 53         add(number[i,j],final,ww)
 54      else
 55         if i=n+1 then
 56            add(start,number[i-1,j],ww)
 57         else
 58            add(number[i,j],number[i-1,j],ww);
 59       end;
 60    for i:=1 to n do
 61       for j:=1 to n+1 do
 62       begin
 63      readln(ww);
 64      if j=1 then
 65         add(start,number[i,j],ww)
 66      else
 67         if j=n+1 then
 68            add(number[i,j-1],final,ww)
 69         else
 70            add(number[i,j-1],number[i,j],ww);
 71       end;
 72    for i:=1 to n+1 do
 73       for j:=1 to n do
 74       begin
 75      readln(ww);
 76      if (i<>1)and(i<>n+1) then
 77         add(number[i-1,j],number[i,j],ww);
 78       end;
 79    for i:=1 to n do
 80       for j:=1 to n+1 do
 81       begin
 82      readln(ww);
 83      if (j<>1)and(j<>n+1) then
 84         add(number[i,j],number[i,j-1],ww);
 85       end;
 86 end; { make_graph }
 87 procedure swap(var aa,bb :longint );
 88 var
 89    tt : longint;
 90 begin
 91    tt:=aa;
 92    aa:=bb;
 93    bb:=tt;
 94 end; { swap }
 95 procedure up(now: longint );
 96 begin
 97    while (d[heap[now]]<d[heap[now>>1]]) do
 98    begin
 99       swap(heap[now],heap[now>>1]);
100       pos[heap[now]]:=now;
101       pos[heap[now>>1]]:=now>>1;
102       now:=now>>1;
103    end;
104 end; { up }
105 procedure down(now :longint );
106 var
107    tmp : longint;
108 begin
109    while now<=(tot>>1) do
110    begin
111       tmp:=now*2;
112       if (tmp+1<=tot)and(d[heap[tmp+1]]<d[heap[tmp]]) then
113      inc(tmp);
114       if d[heap[tmp]]<d[heap[now]] then
115       begin
116      swap(heap[tmp],heap[now]);
117      pos[heap[tmp]]:=tmp;
118      pos[heap[now]]:=now;
119      now:=tmp;
120       end
121       else
122      break;
123    end;
124 end; { down }
125 procedure insect(x :longint );
126 begin
127    inc(tot);
128    heap[tot]:=x;
129    pos[x]:=tot;
130    up(tot);
131 end; { insect }
132 procedure change(x : longint;ww:int64 );
133 begin
134    d[x]:=ww;
135    up(pos[x]);
136 end; { change }
137 function delete():longint;
138 begin
139    delete:=heap[1];
140    swap(heap[1],heap[tot]);
141    dec(tot);
142    pos[heap[1]]:=1;
143    down(1);
144 end; { delete }
145 procedure dijkstra;
146 var
147    i,tmp : longint;
148    t     : node;
149 begin
150    fillchar(d,sizeof(d),63);
151    fillchar(v,sizeof(v),false);
152    d[0]:=0;
153    for i:=start to final do
154       insect(i);
155    for i:=start to final do
156    begin
157       tmp:=delete();
158       v[tmp]:=true;
159       t:=l[tmp];
160       while t<>nil do
161       begin
162      if (not v[t^.goal])and(d[tmp]+t^.w<d[t^.goal]) then
163         change(t^.goal,d[tmp]+t^.w);
164      t:=t^.next;
165       end;
166    end;
167 end; { dijkstra }
168 procedure print;
169 begin
170    writeln(d[final]);
171 end; { print }
172 begin
173    assign(input,'altitude.in');reset(input);
174    assign(output,'altitude.out');rewrite(output);
175    init;
176    make_graph;
177    dijkstra;
178    print;
179    close(input);
180    close(output);
181 end.
posted @ 2012-04-17 07:34  Codinginging  阅读(442)  评论(0编辑  收藏  举报