bzoj 1001

Bzoj 1001

题目大意:在一个平面图上(网格图+斜边),求最小割;

解:因为点数可以去到10000000,所以网络流不行= =,我自己一开始自信满满地说好水啊,结果尼玛直接wa掉了,检查半天不出错,去看discuz,发现是用平面图转构图(参见国家集训队2008day2周冬神牛地论文)然后最短路。自己一个数组写小了,因为特殊的原因,提交在wa和re徘徊,自己检查一晚上代码..还以为是构图写错了,去q群里吐槽一下发现时数组的问题= =,改了立马ac..

View Code
  1 // bzoj 1001 [beijing 2006]
  2 const
  3         maxn=1001;
  4         goal=maxn*maxn;
  5         bilibili=maxlongint >> 1;
  6         inf='1.txt';
  7 type
  8         type_edge=record
  9           cost, dest, next: longint;
 10         end;
 11 var
 12         edge: array[0..maxn*maxn*6]of type_edge;
 13         dist, heap, poss, vect: array[0..maxn*maxn*2]of longint;
 14         hptot, source, sink, n, m, ans, tot: longint;
 15 procedure add(x, y, z: longint);
 16 begin
 17   inc(tot);
 18   with edge[tot] do begin
 19     dest := y;
 20     cost := z;
 21     next := vect[x];
 22     vect[x] := tot;
 23   end;
 24   inc(tot);
 25   with edge[tot] do begin
 26     dest := x;
 27     cost := z;
 28     next := vect[y];
 29     vect[y] := tot;
 30   end;
 31 end;
 32 
 33 procedure init;
 34 var
 35         cost, x, y, i, j: longint;
 36 begin
 37   tot := 0; ans := 0;
 38   fillchar(vect, sizeof(vect), 0);
 39   readln(n, m);
 40   if (n=1)and(m=1) then begin
 41     writeln(0);
 42     close(input); close(output);
 43     halt;
 44   end;                        {key point}
 45   source := 0; sink := (n*(m-1)+(n-1)*m+(m-1)*(n-1))-n*m+2;
 46   for i := 1 to n do begin
 47     for j := 1 to m-1 do begin
 48       read(cost);
 49       //y := (i-1)*2*(m-1)+j; x := y - (m-1);
 50       x := (2*i-3)*(m-1)+j;
 51       y := (2*i-2)*(m-1)+j;
 52       if x<source then x := source;
 53       if y>sink then y := sink;
 54       add(x, y, cost);
 55     end;
 56     //if m<>1 then readln;
 57   end;
 58   for i := 1 to n-1 do begin
 59     for j := 1 to m do begin
 60       read(cost);
 61       //x := 2*(i-1)*(m-1)+j-1; y := x + m;
 62       x := 2*(i-1)*(m-1)+j-1;
 63       y := 2*(i-1)*(m-1)+j-1+m;
 64       if j=1 then x := sink;
 65       if j=m then y := source;
 66       add(x, y, cost);
 67     end;
 68     //if n<>1 then readln;
 69   end;
 70   for i := 1 to n-1 do begin
 71     for j := 1 to m-1 do begin
 72       read(cost);
 73       //x := 2*(i-1)*(m-1)+j; y := x + m - 1;
 74       x := (2*i-2)*(m-1)+j;
 75       y := (2*i-1)*(m-1)+j;
 76       add(x, y, cost);
 77     end;
 78     //readln;
 79   end;
 80 end;
 81 
 82 procedure up(x: longint);
 83 var
 84         tmp, i: longint;
 85 begin
 86   i := x;
 87   tmp := heap[i];
 88   while i>1 do begin
 89     if dist[tmp]<dist[heap[i >> 1]] then begin
 90       heap[i] := heap[i >> 1];
 91       poss[heap[i]] := i;
 92       i := i >> 1;
 93     end
 94       else break;
 95   end;
 96   poss[tmp] := i;
 97   heap[i] := tmp;
 98 end;
 99 
100 procedure down(x: longint);
101 var
102         i, j, tmp: longint;
103 begin
104   i := x;
105   tmp := heap[i];
106   while i << 1 <= hptot do begin
107     j := i << 1;
108     if (j+1<=hptot)and(dist[heap[j]]>dist[heap[j+1]]) then inc(j);
109     if dist[tmp] > dist[heap[j]] then begin
110       heap[i] := heap[j];
111       poss[heap[i]] := i;
112       i := j;
113     end
114       else break;
115   end;
116   poss[tmp] := i;
117   heap[i] := tmp;
118 end;
119 
120 procedure main;
121 var
122         u, i: longint;
123 begin
124   fillchar(poss, sizeof(poss), 0);
125   for i := source to sink do dist[i] := bilibili;
126   hptot := 0; poss[source] := -1;
127   dist[source] := 0; u := source;
128   repeat
129     if u=sink then break;
130     i := vect[u];
131     while i<>0 do
132       with edge[i] do begin
133         if (dist[u] + cost < dist[dest])and(poss[dest]<>-1) then begin
134           dist[dest] := dist[u] + cost;
135           if poss[dest]=0 then begin
136             inc(hptot);
137             poss[dest] := hptot;
138             heap[hptot] := dest;
139             up(hptot);
140           end
141             else up(poss[dest]);
142         end;
143         i := next;
144       end;
145     u := heap[1];
146     poss[u] := -1;
147     heap[1] := heap[hptot];
148     poss[heap[1]] := 1;
149     dec(hptot);
150     down(1);
151   until false;
152   ans := dist[sink];
153 end;
154 
155 procedure print;
156 begin
157   writeln(ans);
158 end;
159 
160 begin
161   assign(input,inf); reset(input);
162   init;
163   main;
164   print;
165 end.
原文地址:https://www.cnblogs.com/wmzisfoolish/p/2440376.html