Problema Calutzi - Pascal

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

{ Andreica Mugurel Ionut }

{$I-,R-,Q-}

Program CAI;

type cal=record

l,c:integer;

end;

var f:text;

pr,last,l,c,i,j,n,p,point,nel:integer;

a,flux,cap:array[0..51,0..51] of integer;

cost:array[0..51,0..51] of longint;

ln,cn,npa,lin,col:integer;

natac,poz:array[1..8] of cal;

costt,fm:longint;

coada:array[1..2500] of cal;

cod:array[1..10000] of integer;

dist:array[0..50] of longint;

incoada:array[0..100] of boolean;

tip,tata:array[0..500] of byte;

begin

assign(f,'cai.in');

reset(f);

readln(f,n,p);

readln(f,ln,cn);

lin:=ln;

col:=cn;
for i:=1 to p do

readln(f,poz[i].l,poz[i].c);

close(f);

npa:=0;

if (ln-2>0) and (cn-1>0) then begin

inc(npa);

natac[npa].l:=ln-2;

natac[npa].c:=cn-1;

end;

if (ln-1>0) and (cn-2>0) then begin

inc(npa);

natac[npa].l:=ln-1;

natac[npa].c:=cn-2;

end;

if (ln-2>0) and (cn+1<=n) then begin

inc(npa);

natac[npa].l:=ln-2;

natac[npa].c:=cn+1;

end;

if (ln-1>0) and (cn+2<=n) then begin

inc(npa);

natac[npa].l:=ln-1;

natac[npa].c:=cn+2;

end;

if (ln+1<=n) and (cn-2>0) then begin

inc(npa);
natac[npa].l:=ln+1;

natac[npa].c:=cn-2;

end;

if (ln+1<=n) and (cn+2<=n) then begin

inc(npa);

natac[npa].l:=ln+1;

natac[npa].c:=cn+2;

end;

if (ln+2<=n) and (cn-1>0) then begin

inc(npa);

natac[npa].l:=ln+2;

natac[npa].c:=cn-1;

end;

if (ln+2<=n) and (cn+1<=n) then begin

inc(npa);

natac[npa].l:=ln+2;

natac[npa].c:=cn+1;

end;

assign(f,'cai.out');

rewrite(f);

if npa>p then begin

writeln(f,'imposibil');

close(f);

halt;

end;
for i:=0 to n+1 do

for j:=0 to n+1 do cost[i,j]:=30000;

for i:=1 to p do begin

nel:=1;

point:=1;

coada[1].l:=poz[i].l;

coada[1].c:=poz[i].c;

for l:=1 to n do

for c:=1 to n do a[l,c]:=30000;

a[poz[i].l,poz[i].c]:=0;

while (point<=nel) do begin

ln:=coada[point].l;

cn:=coada[point].c;

if (ln-2>0) and (cn-1>0) then begin

if (a[ln-2,cn-1]>a[ln,cn]+1) then begin

a[ln-2,cn-1]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln-2;

coada[nel].c:=cn-1;

end;

end;
if (ln-1>0) and (cn-2>0) then begin

if (a[ln-1,cn-2]>a[ln,cn]+1) then begin

a[ln-1,cn-2]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln-1;

coada[nel].c:=cn-2;

end;

end;

if (ln-2>0) and (cn+1<=n) then begin

if (a[ln-2,cn+1]>a[ln,cn]+1) then begin

a[ln-2,cn+1]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln-2;

coada[nel].c:=cn+1;

end;

end;

if (ln-1>0) and (cn+2<=n) then begin

if (a[ln-1,cn+2]>a[ln,cn]+1) then begin

a[ln-1,cn+2]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln-1;

coada[nel].c:=cn+2;

end;

end;

if (ln+1<=n) and (cn-2>0) then begin

if (a[ln+1,cn-2]>a[ln,cn]+1) then begin


a[ln+1,cn-2]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln+1;

coada[nel].c:=cn-2;

end;

end;

if (ln+1<=n) and (cn+2<=n) then begin

if (a[ln+1,cn+2]>a[ln,cn]+1) then begin

a[ln+1,cn+2]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln+1;

coada[nel].c:=cn+2;

end;

end;

if (ln+2<=n) and (cn-1>0) then begin

if (a[ln+2,cn-1]>a[ln,cn]+1) then begin

a[ln+2,cn-1]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln+2;

coada[nel].c:=cn-1;

end;

end;

if (ln+2<=n) and (cn+1<=n) then begin

if (a[ln+2,cn+1]>a[ln,cn]+1) then begin

a[ln+2,cn+1]:=a[ln,cn]+1;

inc(nel);

coada[nel].l:=ln+2;
coada[nel].c:=cn+1;

end;

end;

inc(point);

end;

for j:=1 to npa do begin

cost[i,p+j]:=a[natac[j].l,natac[j].c];

cost[p+j,i]:=-cost[i,p+j];

end;

end;

{ Cuplaj de cost minim }

last:=p+npa+1;

for i:=0 to last do

for j:=0 to last do begin

cap[i,j]:=0;

flux[i,j]:=0;

end;

for i:=1 to p do begin

cap[0,i]:=1;

cost[0,i]:=0;

cost[i,0]:=0;

end;

for j:=1 to p do

for i:=p+1 to p+npa do begin


cap[j,i]:=1;

end;

for i:=p+1 to p+npa do begin

cap[i,last]:=1;

cost[i,last]:=0;

cost[last,i]:=0;

end;

costt:=0;

fm:=0;

repeat

for i:=1 to last do begin

dist[i]:=30000;

incoada[i]:=false;

tata[i]:=255;

end;

point:=1;

nel:=1;

cod[1]:=0;

dist[0]:=0;

tata[0]:=0;

incoada[0]:=true;

while (point<=nel) do begin

for i:=1 to last do

if (dist[i]>dist[cod[point]]+cost[cod[point],i]) then
begin

if (cap[cod[point],i]-flux[cod[point],i]>0) or

((cap[i,cod[point]]>0) and (flux[i,cod[point]]>0))

then begin

dist[i]:=dist[cod[point]]+cost[cod[point],i];

tata[i]:=cod[point];

if (cap[cod[point],i]-flux[cod[point],i]>0) then tip[i]:=1

else tip[i]:=2;

if not incoada[i] then begin

inc(nel);

cod[nel]:=i;

incoada[i]:=true;

end;

end;

end;

incoada[cod[point]]:=false;

inc(point);

end;

if (dist[last]<30000) then begin

pr:=last;

while (pr>0) do begin

case tip[pr] of

1:flux[tata[pr],pr]:=flux[tata[pr],pr]+1;

2:flux[pr,tata[pr]]:=flux[pr,tata[pr]]-1;

end;
pr:=tata[pr];

end;

costt:=costt+dist[last];

fm:=fm+1;

end;

until dist[last]=30000;

writeln(f,costt);

close(f);

end.

You might also like