Đề bài: http://vn.spoj.com/problems/MINCUT/
Thuật toán:
- Với mỗi cách cắt ngang, cắt dọc. Ta chặt nhị phân tìm nhát cắt sao cho độ chênh lệch 2 phần nhỏ nhất.
- Chú ý với mỗi cách cắt ta phải chặt nhị phân 2 lần: value >= trunggian và value <= trunggian
- Các bạn có thể đọc code để hiểu rõ hơn
Code:
uses math;
const fi='';
fo='';
maxn=trunc(1e3)+3;
oo=trunc(1e15);
type data=record
x,y,u,v:longint;
end;
var m,n,i,j,k:longint;
s:array[0..maxn,0..maxn] of int64;
a:array[1..maxn,1..maxn] of longint;
q:array[1..maxn*maxn] of data;
res :int64;
procedure nhap;
begin
assign(input,fi);reset(input);
readln(m,n,k);
for i:=1 to m do
for j:=1 to n do read(a[i,j]);
for i:=1 to k do
with q[i] do
read(x,y,u,v);
close(input);
end;
procedure init;
begin
for i:=1 to m do
for j:=1 to n do s[i,j]:=s[i-1,j]+s[i,j-1]-s[i-1,j-1]+a[i,j];
end;
function tinh(x,y,u,v:longint):int64;
begin
exit(s[u,v]+s[x-1,y-1]-s[x-1,v]-s[u,y-1]);
end;
procedure solve;
var tam,tam2 :int64;
d,c,g :longint;
begin
assign(output,fo);rewrite(output);
for i:=1 to k do
with q[i] do
begin
tam:=tinh(x,y,u,v);
tam2 := tam div 2;
res := oo;
// cat hang
d :=x; c:=u-1;
g := (d+c) div 2;
while (g<>d) and (g<>c) do
begin
if tinh(x,y,g,v)>=tam2 then c:=g else d:=g;
g:=(d+c) div 2;
end;
for g:=c downto d do
if tinh(x,y,g,v)<=tam2 then
begin
res := min(res,tam-2*tinh(x,y,g,v));
end;
d:=x; c:=u-1;
g:=(d+c) div 2;
while (g<>d) and (g<>c) do
begin
if tinh(x,y,g,v)>=tam2 then c:=g else d:=g;
g:=(d+c) div 2;
end;
for g:=d to c do
if tinh(x,y,g,v)>=tam2 then
begin
res := min(res,2*tinh(x,y,g,v)-tam);
end;
// cat cot;
d:=y; c:=v-1;
g:=(d+c) div 2;
while (g<>d) and (g<>c) do
begin
if tinh(x,y,u,g)>=tam2 then c:=g else d:=g;
g:=(d+c) div 2;
end;
for g:=c downto d do
if tinh(x,y,u,g)<=tam2 then
begin
res := min(res,tam-2*tinh(x,y,u,g));
end;
d:=y; c:=v-1;
g:=(d+c) div 2;
while (g<>d) and (g<>c) do
begin
if tinh(x,y,u,g)>=tam2 then c:=g else d:=g;
g:=(d+c) div 2;
end;
for g:=d to c do
if tinh(x,y,u,g)>=tam2 then
begin
res := min(res,2*tinh(x,y,u,g)-tam);
end;
writeln(res);
end;
end;
begin
nhap;
init;
solve;
end.
Speak Your Mind