题目大意

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

左上角点为 (1, 1),右下角点为 (N, M) (上图中N=4, M=4)。有以下三种类型的道路

  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 只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦。

N, M 均小于等于 1000

做法分析

一看就是最小割问题,写的比较好的网络流可以直接暴力的搞过去,当然,正解肯定不是这样,虽然是一个水题,不过还是值得一做的

这题需要利用平面图的对偶图性质

平面图的对偶图很好构造:

  将原图中的面变成新图中的点

  原图中,每条边必定分割了两个面,在新图中,对应的点之间添加一条边,边权还是原图中边的边权

在原图中的一个全局的割就对应了新图中的一个环,也就是说,如果想要求原图中的一个全局最小割,只需要在新图中找一个最小环即可

怎么求出原图中分割固定点 s 和 t(s 和 t 处于一个无线大的平面的边缘) 的一个最小割呢?

  先在原图中添加 s 到 t 的边,给原图增加了一个面

  构造原图的对偶图,把由于增边而增加的新面对应的点设为 S,无穷大的平面对应的点设为 T

  删掉对偶图中 S 到 T 直接相连的边

  求出 S 到 T 的最短路就可以了

详细请看周冬的论文 《两极相通——浅析最大—最小定理在信息学竞赛中的应用》

这题按照上面将的建图,跑最短路就行了,听说 SPFA 也能过,我没试过,用的堆优化的 Dijkstra + 输入外挂直接 516ms 过掉

参考代码

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <queue> using namespace std; const int N=, INF=0x3fffffff, E=N*; struct ARC {
int u, val, next;
inline void init(int a, int b, int c) {
u=a, val=b, next=c;
}
} arc[E];
int head[N], tot, S, T, n, m, dis[N];
bool vs[N]; struct data {
int u, dis;
data() {}
data(int a, int b) : u(a), dis(b) {}
bool operator < (const data &T) const {
return dis>T.dis;
}
}; inline void add_arc(int s, int t, int val) {
arc[tot].init(t, val, head[s]);
head[s]=tot++;
} priority_queue <data> Q;
void Dijkstra() {
fill(dis, dis+T+, INF);
fill(vs, vs+T+, );
while(!Q.empty()) Q.pop();
dis[S]=, Q.push(data(S, ));
for(int u; !Q.empty(); ) {
u=Q.top().u, Q.pop();
if(vs[u]) continue;
if(u==T) {
printf("%d\n", dis[T]);
break;
}
vs[u]=;
for(int e=head[u]; e!=-; e=arc[e].next) {
int v=arc[e].u;
if(vs[v] || dis[u]+arc[e].val>=dis[v]) continue;
dis[v]=dis[u]+arc[e].val;
Q.push(data(v, dis[v]));
}
}
} void read(int &x) {
char c;
while((c=getchar())<'' || c>'');
x=c-'';
while((c=getchar())>='' && c<='') x=(x<<)+(x<<)+c-'';
} void Input() {
for(int i=, id1, id2, a; i<=n-; i++)
for(int j=; j<=m-; j++) {
read(a);
id1=((i-)*(m-)+j)*-;
id2=(i*(m-)+j)*;
if(i==) id1=T;
else if(i==n-) id2=S;
add_arc(id1, id2, a);
add_arc(id2, id1, a);
} for(int i=, id1, id2, a; i<=n-; i++)
for(int j=; j<m; j++) {
read(a);
id1=((i-)*(m-)+j)*;
id2=((i-)*(m-)+j+)*-;
if(j==) id1=S;
else if(j==m-) id2=T;
add_arc(id1, id2, a);
add_arc(id2, id1, a);
} for(int i=, id1, id2, a; i<=n-; i++)
for(int j=; j<=m-; j++) {
read(a);
id1=((i-)*(m-)+j)*;
id2=((i-)*(m-)+j)*-;
add_arc(id1, id2, a);
add_arc(id2, id1, a);
}
} int main() {
read(n), read(m);
S=, T=(n-)*(m-)*+;
fill(head, head+T+, -), tot=;
if(n== || m==) {
if(n>m) swap(n, m);
int ans=INF;
for(int i=, a; i<m; i++) {
read(a);
if(ans>a) ans=a;
}
printf("%d\n", ans==INF?:ans);
}
else Input(), Dijkstra();
return ;
}

BZOJ 1001

题目链接 & AC 通道

BZOJ 1001 [BeiJing2006] 狼抓兔子

BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)的更多相关文章

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

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

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

    平面图跑最大流 可以转换为其对偶图跑最短路 一个环对应一个割  找到最小环(即最短路)极为所求,注意辅助边的建立 加入读入优化  不过时间还是一般  估计是dij写的不好   大神勿喷~~~ /*** ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 转:nginx基础概念(request)

    这节我们讲request,在nginx中我们指的是http请求,具体到nginx中的数据结构是ngx_http_request_t.ngx_http_request_t是对一个http请求的封装. 我 ...

  2. JavaScript事件详解-zepto的事件实现

    zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...

  3. js手风琴图片切换实现原理及函数分析

    关键词: js手风琴 js百叶窗 js百页窗 实现原理解读 使用两层for循环实现, 第一层有三个功能,分别给第个li: 添加索引 预设位置 添加事件 第二层有两个功能,整理图片位置: 鼠标的li,以 ...

  4. ooj 1066 青蛙过河DP

    http://121.249.217.157/JudgeOnline/problem.php?id=1066 1066: 青蛙过河 时间限制: 1 Sec  内存限制: 64 MB提交: 58  解决 ...

  5. WebView上实现Java与JavaScript交互

    在安卓开发上,考虑到开发效率和界面更新,有时使用WebView结合web页面技术,可以快速迭代地开发移动应用.WebView加载资源的速度并不慢,但是如果资源多了,就很慢.图片.css.js.html ...

  6. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)

    一.前提: 完成Hello Game项目的创建编译. 具体参考:Cocos2dx.3x_Hello Game项目创建篇 二.本篇目标: l  说说关于塔防游戏的想法和思路 l  实现一个简单的塔防游戏 ...

  7. 和View Controllers一起工作

    在这一课中,你会继续在FoodTracker菜谱的场景工作.你会重新安排现有的UI元素并使用图像采集器添加到照片用户界面.当你完成,你的应用程序将是这个样子: 学习目标 在课程结束时,你将能够: 了解 ...

  8. memcpy memmove区别和实现

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...

  9. Core Java - 流(Stream) - 字节流和字符流(一)

    0. 概述: Java中基于流的I/O构建在4个抽象类之上, 其中2个是字节流,另外2个是字符流. 字节流: InputStream / OutputStream 当操作字节或其它二进制对象时,应当使 ...

  10. 使用dynamic类型改进反射

    首先还是声明一下,使用场景: 1.如果编译时函数名称确定,对象类型运行时确定,那么运用dynamic是一个好主意.2.如果编译时函数名称确定,对象类型在编译时也确定,那就既不需要反射也不需要dynam ...