poj 2711 Leapin' Lizards 拆点构图最大流

来源:互联网 发布:网络延迟单位 编辑:程序博客网 时间:2024/06/06 23:18

题意:给了两个(x,y)地图..其实是描述的一张图..第一张图说明图中的每个点至多有多少个lizard出去..第二张图说明哪些位置有lizard..现在告诉lizard每次的最远移动距离..而图中任意两点的距离为其曼哈顿距离...问能否让所有的lizard走出地图...

题解:一个点拆成"起点"和"终点"..“起点"到"终点"的流量为最大离开的lizard个数...而超级源点与每个有'L'点的"起点"做边.容量为1..而若一个点可以一步走出去..则其与超级汇点做边..容量为无穷大..然后根据各点能到达的情况做边..跑一次最大流找出最多能跑出去的lizard个数..用总数减去它就是答案..值得注意的是输出要看清..

代码:

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(u);  for l:=1 to u do  begin    fillchar(c,sizeof(c),0);    readln(n,d1);    readln(s1);    m:=length(s1);    for i:=1 to m do      a[1,i]:=s1[i];    for i:=2 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('Case #',l,': ');    if tot-ans=0      then writeln('no lizard was left behind.')      else if tot-ans=1             then writeln(1,' lizard was left behind.')             else writeln(tot-ans,' lizards were left behind.');  end;end.


0 0
原创粉丝点击