拆点构图最大流
代码:
var u,l,n,m,i,j,ans,tot,s,t,x,e,d1,num:longint; c:array[1..1000,1..1000] of longint; fa:array[0..1000] of longint; a:array[1..20,1..20] of char; s1:string; w:char; procedure work(x,y:longint); var i,j,p1,q1,p2,q2:longint; begin for i:=1 to n do for j:=1 to m do if (sqrt(sqr(i-x)+sqr(j-y))<=d1)and(a[i,j]<>'0')and((i<>x)or(j<>y)) then begin p1:=((i-1)*m+j)*2-1; q1:=((i-1)*m+j)*2; p2:=((x-1)*m+y)*2-1; q2:=((x-1)*m+y)*2; c[q2,p1]:=maxlongint; c[q1,p2]:=maxlongint; end; end; function find(x:longint):boolean; var i:longint; begin if x=t then exit(true); find:=false; for i:=1 to n*2*m+2 do if (fa[i]=-1)and(c[x,i]>0) then begin fa[i]:=x; if find(i) then exit(true); end; end; procedure change; var min,i:longint; begin min:=maxlongint; i:=t; while i<>s do begin if c[fa[i],i]<min then min:=c[fa[i],i]; i:=fa[i]; end; ans:=ans+min; i:=t; while i<>s do begin dec(c[fa[i],i]); inc(c[i,fa[i]]); i:=fa[i]; end; end; procedure main; var i:longint; begin for i:=1 to n*m*2+2 do fa[i]:=-1; fa[s]:=0; while find(s) do begin change; for i:=1 to n*m*2+2 do fa[i]:=-1; fa[s]:=0; end; end; begin readln(n,m,d1); for i:=1 to n do for j:=1 to m do if j<m then read(a[i,j]) else readln(a[i,j]); for i:=1 to n do for j:=1 to m do if a[i,j]<>'0' then begin val(a[i,j],x); c[((i-1)*m+j)*2-1,((i-1)*m+j)*2]:=x;; end; for i:=1 to n do for j:=1 to m do if a[i,j]<>'0' then work(i,j); s:=n*m*2+1; t:=n*m*2+2; tot:=0; for i:=1 to n do for j:=1 to m do begin if j<m then read(w) else readln(w); if w='L' then begin inc(tot); c[s,((i-1)*m+j)*2-1]:=1; end; end; for i:=1 to n do for j:=1 to m do if (a[i,j]<>'0')and((i<=d1)or(j<=d1)or(n-i+1<=d1)or(m-j+1<=d1)) then c[((i-1)*m+j)*2,t]:=maxlongint; ans:=0; main; write(tot-ans); end.