码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1001: [BeiJing2006]狼抓兔子 最短路+对偶图

时间:2016-05-12 16:20:41      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

题意:求一个表格图的最小割。


分析:这题如果套上一个网络流的话是会挂的,所以我们要把该图转换成它的对偶图,具体方法可以参照两级相通————浅析最大最小定理在信息学竞赛中的应用 By 周冬。然后跑对短路就好了。

良心的出题人居然没卡spfa


这题要特判n=1 or m=1的情况

这次一开始无限12msWA的原因是spfa的结束条件是until head>=tail,而我用的是循环队列……不想多说,以后一定要注意才行啊。


代码:

const
  maxn=2000009;

var
  s,t,n,m,e:longint;
  last,d,state:array[0..maxn] of longint;
  side:array[1..maxn*3] of record
    x,y,z,next:longint;
  end;
  v:array[0..maxn] of boolean;
  flag:boolean;

procedure add(x,y,z:longint);
begin
  inc(e);
  side[e].x:=x; side[e].y:=y; side[e].z:=z;
  side[e].next:=last[x]; last[x]:=e;
  inc(e);
  side[e].x:=y; side[e].y:=x; side[e].z:=z;
  side[e].next:=last[y]; last[y]:=e;
end;

procedure init;
var
  i,j,ans,x:longint;
begin
  ans:=maxlongint;
  readln(n,m);
  flag:=true;
  if (n=1)or(m=1) then flag:=false;
  if (n=1)and(m=1) then
  begin
    writeln(0);
    exit;
  end;
  if n=1 then
  begin
    for i:=1 to m-1 do
    begin
      read(x);
      if x<ans then ans:=x;
    end;
    writeln(ans);
    exit;
  end;
  if m=1 then
  begin
    for i:=1 to n-1 do
    begin
      read(x);
      if x<ans then ans:=x;
    end;
    writeln(ans);
    exit;
  end;
  s:=0;
  t:=2*(n-1)*(m-1)+1;
  for i:=1 to m-1 do
  begin
    read(x);
    add(i*2,t,x);
  end;
  for i:=2 to n-1 do
    for j:=1 to m-1 do
    begin
      read(x);
      add(2*(i-1)*(m-1)+j*2,2*(i-2)*(m-1)+j*2-1,x);
    end;
  for i:=1 to m-1 do
  begin
    read(x);
    add(s,2*(n-2)*(m-1)+i*2-1,x)
  end;
  for i:=1 to n-1 do
  begin
    read(x);
    add(s,2*(i-1)*(m-1)+1,x);
    for j:=2 to m-1 do
    begin
      read(x);
      add(2*(i-1)*(m-1)+2*j-1,2*(i-1)*(m-1)+2*(j-1),x);
    end;
    read(x);
    add(t,2*(i-1)*(m-1)+2*m-2,x);
  end;
  for i:=1 to n-1 do
    for j:=1 to m-1 do
    begin
      read(x);
      add(2*(i-1)*(m-1)+2*j-1,2*(i-1)*(m-1)+2*j,x);
    end;
end;

procedure spfa;
var
  head,tail,i,u:longint;
begin
  fillchar(d,sizeof(d),$7f div 3);
  d[s]:=0;
  fillchar(v,sizeof(v),true);
  v[s]:=false;
  head:=0;
  tail:=1;
  state[1]:=s;
  repeat
    inc(head);
    if head>t+7 then head:=1;
    u:=state[head];
    i:=last[u];
    while i>0 do
      with side[i] do
      begin
        if d[x]+z<d[y] then
        begin
          d[y]:=d[x]+z;
          if v[y] then
          begin
            v[y]:=false;
            inc(tail);
            if tail>t+7 then tail:=1;
            state[tail]:=y;
          end;
        end;
        i:=next;
      end;
    v[u]:=true;
  until head=tail;
  writeln(d[t]);
end;

begin
  init;
  if flag then spfa;
end.


bzoj 1001: [BeiJing2006]狼抓兔子 最短路+对偶图

标签:

原文地址:http://blog.csdn.net/qq_33229466/article/details/51366171

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!