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.