bzoj 1066: [SCOI2007]蜥蜴

拆点构图最大流

代码:

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.


你可能感兴趣的:(bzoj 1066: [SCOI2007]蜥蜴)