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

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

分析:这题如果套上一个网络流的话是会挂的,所以我们要把该图转换成它的对偶图,具体方法可以参照两级相通————浅析最大最小定理在信息学竞赛中的应用 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.
时间: 2024-10-01 07:37:28

bzoj 1001: [BeiJing2006]狼抓兔子 最短路+对偶图的相关文章

BZOJ 1001: [BeiJing2006]狼抓兔子(最短路)

平面图的最小割转化为对偶图的最短路(资料:两极相通——浅析最大最小定理在信息学竞赛中的应用) ,然后DIJKSTRA就OK了. ------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<que

BZOJ 1001: [BeiJing2006]狼抓兔子 对偶图

本题是最大流转最小割转对偶图最短路 推荐周东的<浅析最大最小定理在信息学竞赛中的应用> 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 12166  Solved: 2866 [Submit][Status][Discuss] Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在

BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】

1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 23822  Solved: 6012[Submit][Status][Discuss] Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M

BZOJ 1001 [BeiJing2006]狼抓兔子 平面图最大流

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是

BZOJ 1001: [BeiJing2006]狼抓兔子 最小割

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)

bzoj 1001 [BeiJing2006]狼抓兔子 最小割+最短路

题面 题目传送门 解法 将最大流转化成最小割,然后跑最短路即可 具体如何见图可以参考下图 尽量用dijkstra 代码 #include <bits/stdc++.h> #define PI pair <int, int> #define mp make_pair #define N 1010 using namespace std; template <typename node> void chkmax(node &x, node y) {x = max(x

bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割

平面图跑最大流 可以转换为其对偶图跑最短路 一个环对应一个割  找到最小环(即最短路)极为所求,注意辅助边的建立 加入读入优化  不过时间还是一般  估计是dij写的不好   大神勿喷~~~ /************************************************************** Problem: 1001 User: 96655 Language: C++ Result: Accepted Time:1724 ms Memory:95120 kb ****

BZOJ 1001 [BeiJing2006]狼抓兔子

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 题意: ... 很容易想到求的是一个最小割=最大流. 之前一直用的刘汝佳的模板STL过题,很久没用过数组模拟了. 再次熟悉一下写法,first数组是索引数组,标记的结点的最后一条边,利用next数组找到上一条边. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define N 1100000 6 int n,m,

【BZOJ】1001: [BeiJing2006]狼抓兔子

1001: [BeiJing2006]狼抓兔子 Description 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下 三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下角(N,M)的窝中去,狼王开始伏击