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.