bzoj1001: [BeiJing2006]狼抓兔子

题目链接http://www.lydsy.com:808/JudgeOnline/problem.php?id=1001

可以很显然地看出来这道题是一个裸的最大流,但是边数是10^6级别的,不T才怪。

平面图上最大流等于他的最小割,这是挺显然的吧,因为斜着这么插过去肯定要经过所有的流量。

所以我们求它的对偶图,以左下为s,右上为t,求一次最短路径就是最小割了。

用dijkstra+heap实现,这时候c++的巨大优势就体现出来了

(其实是我当时太弱了不会spfa)(注意m=1或n=1的时候要特判,因为它wa好几次)

代码:

  1 program xx;
  2 uses math;
  3  
  4 type xxx=record
  5        key,pos:longint;
  6 end;
  7  
  8 var heng,shu,xie:array[0..1110,0..1110] of longint;
  9     i,j,k,n,m,p,q,r,en,tot,node,ans:longint;
 10     dis,inh:array[0..2500010] of longint;
 11     heap:array[0..2500010] of xxx;
 12     ed,len:array[0..2500010,1..3] of longint;
 13     vis:array[0..2500010] of boolean;
 14  
 15 procedure swap(var a,b:xxx);
 16 var t:xxx;
 17 begin
 18   t:=a;
 19   a:=b;
 20   b:=t;
 21 end;
 22  
 23 procedure swapn(var a,b:longint);
 24 var t:longint;
 25 begin
 26   t:=a;
 27   a:=b;
 28   b:=t;
 29 end;
 30  
 31 procedure link2(x:longint);
 32 begin
 33   if i mod j=0
 34   then
 35     begin
 36       ed[x,1]:=en;
 37       len[x,1]:=shu[(i-1) div j+1,m];
 38     end
 39   else
 40     begin
 41       ed[x,1]:=x+1;
 42       len[x,1]:=shu[(i-1) div j+1,(i-1) mod j shr 1+2];
 43     end;
 44   if i>j then
 45     begin
 46       ed[x,2]:=x-j-1;
 47       len[x,2]:=heng[(i-1) div j+1,(i-1) mod j shr 1+1];
 48     end
 49   else begin
 50          ed[x,2]:=en;
 51          len[x,2]:=heng[1,i shr 1];
 52        end;
 53   ed[x,3]:=x-1;
 54   len[x,3]:=xie[(i-1) div j+1,(i-1) mod j shr 1+1];
 55 end;
 56  
 57 procedure link1(x:longint);
 58 begin
 59   if i mod j<>1 then
 60     begin
 61       ed[x,1]:=x-1;
 62       len[x,1]:=shu[(i-1) div j+1,(i-1) mod j shr 1+1];
 63     end;
 64   if i<en-j then
 65     begin
 66       ed[x,2]:=x+j+1;
 67       len[x,2]:=heng[(i-1) div j+2,(i-1) mod j shr 1+1];
 68     end;
 69   ed[x,3]:=x+1;
 70   len[x,3]:=xie[(i-1) div j+1,(i-1) mod j shr 1+1];
 71 end;
 72  
 73 procedure insert(x,y,node:longint);
 74 begin
 75   heap[x].key:=y;
 76   heap[x].pos:=node;
 77   inh[node]:=x;
 78   while (x<>1) and (heap[x].key<heap[x shr 1].key) do
 79     begin
 80       swapn(inh[heap[x].pos],inh[heap[x shr 1].pos]);
 81       swap(heap[x],heap[x shr 1]);
 82       x:=x shr 1;
 83     end;
 84 end;
 85  
 86 procedure delete(x:longint);
 87 var k:longint;
 88 begin
 89   swapn(inh[heap[x].pos],inh[heap[tot].pos]);
 90   swap(heap[x],heap[tot]);
 91   heap[tot].key:=maxlongint;
 92   inh[heap[tot].pos]:=0;
 93   heap[tot].pos:=0;
 94   while x shl 1<=tot-1 do
 95     begin
 96       if heap[x shl 1].key<heap[x shl 1+1].key
 97       then k:=x shl 1
 98       else k:=x shl 1+1;
 99       if heap[x].key>heap[k].key
100       then
101         begin
102           swapn(inh[heap[x].pos],inh[heap[k].pos]);
103           swap(heap[x],heap[k]);
104           x:=k;
105         end
106       else break
107     end;
108 end;
109  
110 begin
111   readln(n,m);
112   ans:=maxlongint;
113   for i:=1 to n do
114     for j:=1 to m-1 do
115       begin
116         read(heng[i,j]);
117         ans:=min(ans,heng[i,j]);
118       end;
119   for i:=1 to n-1 do
120     for j:=1 to m do
121       begin
122         read(shu[i,j]);
123         ans:=min(ans,shu[i,j]);
124       end;
125   for i:=1 to n-1 do
126     for j:=1 to m-1 do
127       begin
128         read(xie[i,j]);
129         ans:=min(xie[i,j],ans);
130       end;
131   if (n=1) or (m=1) then
132     begin
133       writeln(ans);
134       exit;
135     end;
136   en:=(n-1)*(m-1) shl 1+1;
137   j:=2*(m-1);
138   heap[en].key:=maxlongint;
139   dis[en]:=maxlongint;
140   for i:=1 to (n-1)*(m-1)*2 do
141     begin
142       dis[i]:=maxlongint;
143       heap[i].key:=maxlongint;
144       if i mod (2*(m-1))=1 then dis[i]:=min(dis[i],shu[(i-1) div j+1,1]);
145       if (i mod 2=1) and ((i-1) div j+2>=n)
146       then dis[i]:=min(dis[i],heng[n,(i-1) mod j shr 1+1]);
147       if dis[i]<>maxlongint then
148         begin
149           inc(tot);
150           insert(tot,dis[i],i);
151         end;
152       if i mod 2=0
153       then link2(i)
154       else link1(i);
155     end;
156   while tot>0 do
157     begin
158       node:=heap[1].pos;
159       if node=en then
160         begin
161           writeln(dis[en]);
162           exit;
163         end;
164       if not(vis[node]) then
165       for i:=1 to 3 do
166         if ed[node,i]<>0 then
167           begin
168             k:=ed[node,i];
169             if dis[node]+len[node,i]<dis[k] then
170               begin
171                 dis[k]:=dis[node]+len[node,i];
172                 if inh[k]=0
173                 then
174                   begin
175                     inc(tot);
176                     insert(tot,dis[k],k);
177                   end
178                 else insert(inh[k],dis[k],k);
179               end;
180           end;
181       delete(1);
182       dec(tot);
183       vis[node]:=true;
184     end;
185   writeln(dis[en]);
186 end.
View Code

 

posted @ 2014-11-15 11:10  chambist  Views(163)  Comments(0Edit  收藏  举报