1001: [BeiJing2006]狼抓兔子

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 23822  Solved: 6012
[Submit][Status][Discuss]

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)的窝中去,狼王开始伏击
这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.

Input

第一行为N,M.表示网格的大小,N,M均小于等于1000.
接下来分三部分
第一部分共N行,每行M-1个数,表示横向道路的权值. 
第二部分共N-1行,每行M个数,表示纵向道路的权值. 
第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 
输入文件保证不超过10M

Output

输出一个整数,表示参与伏击的狼的最小数量.

Sample Input

3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6

Sample Output

14

HINT

2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

Source

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001

分析:最大流写法如下:

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
inline int read()
{
int x=,f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<)
{
putchar('-');
x=-x;
}
if(x>)
{
write(x/);
}
putchar(x%+'');
}
int ne;
const int N=;
struct data
{
int to,next,v;
}e[N<<];
int head[N];
int h[N],q[N],ans;
inline void update(int u,int v,int w)
{
ne++;
e[ne].to=v;
e[ne].v=w;
e[ne].next=head[u];
head[u]=ne;
}
inline bool BFS()
{
int now,i;
memset(h,-,sizeof(h));
int t=,w=;
q[t]=;
h[]=;
while(t<w)
{
now=q[t];
t++;
i=head[now];
while(i)
{
if(e[i].v&&h[e[i].to]<)
{
q[w++]=e[i].to;
h[e[i].to]=h[now]+;
}
i=e[i].next;
}
}
if(h[n*m]==-)
return false;
return true;
}
inline int DFS(int x,int f)
{
if(x==n*m)
return f;
int i=head[x];
int w,used=;
while(i)
{
if(e[i].v&&h[e[i].to]==h[x]+)
{
w=f-used;
w=DFS(e[i].to,min(w,e[i].v));
e[i].v-=w;
e[i+].v+=w;
used+=w;
if(used==f)
return f;
}
i=e[i].next;
}
if(!used)
h[x]=-;
return used;
}
inline void dinic()
{
while(BFS())
{
ans+=DFS(,0x7f7f7f7f);
}
}
int main()
{
n=read();
m=read();
int x;
for(int i=;i<=n;i++)
{
for(int j=;j<m;j++)
{
x=read();
update(m*(i-)+j,m*(i-)+j+,x);
update(m*(i-)+j+,m*(i-)+j,x);
}
}
for(int i=;i<n;i++)
{
for(int j=;j<=m;j++)
{
x=read();
update(m*(i-)+j,m*(i)+j,x);
update(m*(i)+j,m*(i-)+j,x);
}
}
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
x=read();
update(m*(i-)+j,m*(i)+j+,x);
update(m*(i)+j+,m*(i-)+j,x);
}
}
dinic();
write(ans);
return ;
}

分析:最小割,上网看了别人的博客,学习到了s-t平面图的最小割的解法,把原图中的面看作点,起点和终点都等同于最外面的那一个面,原图中一条边权值为w,新图中就等同于此边在平面图中分割开的两个面(即新图中两个点)连一条边,权值为w。建模完成后,新图中的起点和终点的一条路径就穿插过原图的一些边,即一条路径等于原图中的一个割,所以最小割就等于新图的最短路径长度。确实很厉害。

推荐文章:浅析最大最小定理在信息学竞赛中的应用》--周冬

下面给出SPFA+最小割代码:

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')
f=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<)
{
putchar('-');
x=-x;
}
if(x>)
{
write(x/);
}
putchar(x%+'');
}
#define M 2000001
int n,m,nm;
struct data
{
int to,next,v;
}e[*M];
int dis[M],q[M],head[M];
bool flag[M];
int ne;
inline void update(int u,int v,int w)
{
ne++;
e[ne].to=v;
e[ne].v=w;
e[ne].next=head[u];
head[u]=ne;
ne++;
e[ne].to=u;
e[ne].v=w;
e[ne].next=head[v];
head[v]=ne;
}
inline void spfa()
{
memset(dis,0x3f,sizeof(dis));
int i,t=,w=;
dis[]=q[w]=;flag[]=;
while(t!=w)
{
int u=q[t++];
flag[u]=;
if(t==M)t=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[u]+e[i].v)
{
dis[v]=dis[u]+e[i].v;
if(flag[v]==)
{
flag[v]=;
q[w++]=v;
if(w==M)w=;
}
}
}
}
}
int main()
{
n=read();
m=read();
nm=(n*m-m-n+)<<;
int x;
for(int j=;j<m;j++)
{
x=read();
update(j,nm+,x);
}
for(int i=;i<n-;i++)
{
for(int j=;j<m;j++)
{
x=read();
update((i<<)*(m-)+j,((i<<)-)*(m-)+j,x);
}
}
for(int j=;j<m;j++)
{
x=read();
update(,((n<<)-)*(m-)+j,x);
}
for(int i=;i<n-;i++)
{
for(int j=;j<=m;j++)
{
x=read();
if(j==)
update(,(i<<)*(m-)+m,x);
else if(j==m)
update((i<<|)*(m-),nm+,x);
else
update((i<<)*(m-)+j-,(i<<)*(m-)+j+m-,x);
}
}
for(int i=;i<n-;i++)
{
for(int j=;j<m;j++)
{
x=read();
update((i<<|)*(m-)+j,(i<<)*(m-)+j,x);
}
}
spfa();
write(dis[nm+]);
return ;
}

BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】的更多相关文章

  1. BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)

    题目大意 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的.而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  2. BZOJ 1001: [BeiJing2006]狼抓兔子

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 20029  Solved: 4957[Submit][ ...

  3. BZOJ 1001 [BeiJing2006]狼抓兔子 (UVA 1376 Animal Run)

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 24727  Solved: 6276[Submit][ ...

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

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

  5. BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1001 题意: 思路:这道题目是最小割题目,但是吧你直接套用Dinic是会超时的. 这里有种很奇妙的做 ...

  6. [bzoj1001][BeiJing2006]狼抓兔子_网络流_最小割转对偶图

    狼抓兔子 bzoj-1001 BeiJing2006 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还 ...

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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓 ...

  8. [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)

    Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...

  9. 【刷题】BZOJ 1001 [BeiJing2006]狼抓兔子

    Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...

随机推荐

  1. 【java】缓冲字符字节输入输出流:java.io.BufferedReader、java.io.BufferedWriter、java.io.BufferedInputStream、java.io.BufferedOutputStream

    BufferedReader最重要,因为有个方法public String readLine() package System输入输出; import java.io.BufferedReader; ...

  2. 2.sass变量、嵌套、混合(mixin)、继承拓展、@import、comment

    变量.嵌套.混合(mixin).继承拓展.@import.comment 变量的意义 在sass里我们可以定义多个变量来存放颜色.边框等等的样式,这样就可以在下面想要使用样式的时候使用变量了 这样的优 ...

  3. Docker 安装入门 --基础镜像

    安装Docker1.Docker命令安装 yum install docker //安装docker包 service docker start //设置服务启动  chkconfig docker ...

  4. lesson - 8 课程笔记 tar / gzip /bzip2 / xz /

    作用:为linux的文件和目录创建档案,也可以在档案中改变文件,或者向档案中加入新的文件即用来压缩和解压文件.tar本身不具有压缩功能.他是调用压缩功能实现的  语法:tar[必要参数][选择参数][ ...

  5. [经验分享]WebAPI中返回类型JsonMessage的应用

    这是一个绝无仅有的好类型,一个你爱不释手的好类型,好了,不扯了,直接上干货. 相信大家都知道,在调用接口的时候返回Json数据已经成为一种不成文的标准,因为它的解析快,易读等优秀的特性,所以被绝大多数 ...

  6. unity图片后期处理

    处理算法如下,在Start方法中分别调用想要的效果就行了.其中,将你需要处理的 图片 拖拽到 image参数上.注意,如果想要图片保持原来的尺寸不被压缩,需要更改图片的导入设置如下图,主要的Textu ...

  7. 伽罗瓦域(有限域)GFq^12上元素的1→2→4→12塔式扩张(2)------第二次扩张

    接上文https://www.cnblogs.com/heshuchao/p/8196307.html 继续探讨塔式扩张的第二部分,即1→2→4→12中2 → 4的元素扩张表示方式与计算公式推导. 3 ...

  8. Q:算法(第四版)—第一章

    1.1.14:编写一个静态方法lg(),接受一个整型参数N,返回不大于log2N的最大整数(ps:不使用Math库) 分析: 利用将公式k=log2N转化为N=2k的原理,不断的逼近其输入的值N,当N ...

  9. 总结oninput、onchange与onpropertychange事件的用法和区别

    前端页面开发的很多情况下都需要实时监听文本框输入,比如腾讯微博编写140字的微博时输入框hu9i动态显示还可以输入的字数.过去一般都使用onchange/onkeyup/onkeypress/onke ...

  10. Scrum And Teamwork

    Scrum Learning 概念 Scrum是迭代式增量软件开发过程,通常用于敏捷软件开发.Scrum包括了一系列实践和预定义角色的过程骨架.Scrum中的主要角色包括同项目经理类似的Scrum主管 ...