【解题思路】

  显然,这题的答案是这个网格图的最小割。根据最大流-最小割定理,我们可以用网络流算法来求其最小割,时间复杂度最小为O(V2√E)。

  特殊的,这个网格图是一个平面图,于是可以根据平面图最小割-最短路定理,转化为其对偶图的最短路,时间复杂度最小为O(kE)或O(Vlog2V)(民科算法spfa前途不可估量)。

【参考代码】

  恩,听说这题我当初RE得生活不能自理,于是直接贴了orz::hzwer大神的代码。。

  贴个T掉的SAP板子。。(已修正了假板子的当前弧优化。。但还是T得生活不能自理。。)

 #pragma GCC optimize(2)
#include <algorithm>
#include <cstring>
#include <functional>
#define REP(i,low,high) for(register int i=(low);i<=(high);++i)
#define INF (0x7f7f7f7f)
#define function(type) __attribute__((optimize("-O2"))) inline type
#define procedure __attribute__((optimize("-O2"))) inline void
using namespace std; //ex_cmp {
template<typename T,class Compare>
inline bool getcmp(T&target,const T&pattern,Compare comp)
{
return comp(pattern,target)?target=pattern,:;
}
//} ex_cmp //quick_io {
#include <cctype>
#include <cstdio>
function(int) getint()
{
char c=getchar(); for(;!isdigit(c)&&c!='-';c=getchar());
short s=; for(;c=='-';c=getchar()) s*=-; int r=;
for(;isdigit(c);c=getchar()) r=(r<<)+(r<<)+c-'';
return s*r;
}
//} quick_io static const int N=,M=; static int cardE=; struct edge
{
int fr,to,cap;
edge(const int&f=,const int&t=,const int&c=)
:fr(f),to(t),cap(c) {}
}edg[(M<<)+]; int hed[N+],nxt[(M<<)+],hsh[][]; procedure add_edge(const int&fr,const int&to,const int&cp)
{
edg[cardE]=edge(fr,to,cp),nxt[cardE]=hed[fr],hed[fr]=cardE++;
} //SAP {
int aug[N+],cur[N+],dis[N+],gap[N+],path[N+]; function(int) augment(const int&S,const int&T)
{
for(register int i=T;i!=S;i=edg[path[i]].fr)
{
edg[path[i]].cap-=aug[T],edg[path[i]^].cap+=aug[T];
}
return aug[T];
} function(int) SAP(const int&S,const int&T,const int&N)
{
memset(aug,,sizeof aug),memset(gap,,sizeof gap);
memset(dis,,sizeof dis); REP(i,,N) cur[i]=hed[i];
aug[S]=INF,gap[]=N; int ret=;
for(register int fr=S;dis[S]<N;)
{
if(fr==T) ret+=augment(fr=S,T); bool flag=;
for(register int i=cur[fr];~i;i=nxt[i])
{
int to=edg[i].to;
if(edg[i].cap&&dis[fr]==dis[to]+)
{
aug[to]=min(aug[fr],edg[i].cap)
,path[to]=cur[fr]=i,fr=to,flag=; break;
}
}
if(flag)
{
if(!--gap[dis[fr]]) break; dis[fr]=N;
for(register int i=hed[fr];~i;i=nxt[i])
if(edg[i].cap)
{
getcmp(dis[fr],dis[edg[i].to]+,less<int>());
}
++gap[dis[fr]],cur[fr]=hed[fr];
if(fr!=S) fr=edg[path[fr]].fr;
}
}
return ret;
}
//} SAP int main()
{
int n=getint(),m=getint(),cardP=;
REP(i,,n) REP(j,,m) hsh[i][j]=++cardP;
memset(hed,-,sizeof hed),memset(nxt,-,sizeof nxt);
REP(i,,n) REP(j,,m)
{
int w=getint();
add_edge(hsh[i][j-],hsh[i][j],w),
add_edge(hsh[i][j],hsh[i][j-],w);
}
REP(i,,n) REP(j,,m)
{
int w=getint();
add_edge(hsh[i-][j],hsh[i][j],w),
add_edge(hsh[i][j],hsh[i-][j],w);
}
REP(i,,n) REP(j,,m)
{
int w=getint();
add_edge(hsh[i-][j-],hsh[i][j],w),
add_edge(hsh[i][j],hsh[i-][j-],w);
}
printf("%d\n",SAP(,cardP,cardP));
return ;
}

  然后对偶图最短路。。(被队列长度卡了好久。。用了循环队列才过。。)

 #pragma GCC optimize(2)
#include <algorithm>
#include <cstring>
#include <functional>
#define REP(i,low,high) for(register int i=(low);i<=(high);++i)
#define INF (0x3f3f3f3f)
#define function(type) __attribute__((optimize("-O2"))) inline type
#define procedure __attribute__((optimize("-O2"))) inline void
using namespace std; //ex_cmp {
template<typename T,class Compare>
inline bool getcmp(T&target,const T&pattern,Compare comp)
{
return comp(pattern,target)?target=pattern,:;
}
//} ex_cmp //quick_io {
#include <cctype>
#include <cstdio>
function(long long) getint()
{
char c=getchar(); for(;!isdigit(c)&&c!='+'&&c!='-';c=getchar());
short s=; for(;c=='+'||c=='-';c=getchar()) if(c=='-') s*=-;
long long r=; for(;isdigit(c);c=getchar()) r=(r<<)+(r<<)+c-'';
return s*r;
}
//} quick_io static const int N=,M=,SIZE=(N<<)+; struct edge
{
int to,cap; edge(const int&t=,const int&c=):to(t),cap(c) {}
}edg[(M<<)+]; static int cardE=; int hed[N+],nxt[(M<<)+]; procedure add_edge(const int&fr,const int&to,const int&cp)
{
edg[++cardE]=edge(to,cp),nxt[cardE]=hed[fr],hed[fr]=cardE;
} //SPFA {
bool inq[N+]={}; int dis[N+]={},q[SIZE]; function(int&) move(int&n) {return ++n==SIZE?n=:n;} function(int) SPFA(const int&S,const int&T)
{
memset(dis,0x3f,sizeof dis),inq[q[dis[S]=]=S]=;
for(register int head=-,tail=;head!=tail;)
{
int fr=q[move(head)];
for(register int i=hed[fr];i;i=nxt[i])
{
int to=edg[i].to;
if(
getcmp(dis[to],dis[fr]+edg[i].cap,less<int>())
&&!inq[to]
) inq[q[move(tail)]=to]=;
}
inq[fr]=;
}
return dis[T];
}
//} SPFA int main()
{
int n=getint(),m=getint(),nm=(n-)*(m-)<<;
if(n==||m==)
{
int ans=INF;
REP(i,,max(m,n)-) getcmp(ans,(int)getint(),less<int>());
return printf("%d\n",ans),;
}
REP(i,,m-)
{
int w=getint(); add_edge(i,nm+,w),add_edge(nm+,i,w);
}
REP(i,,n-) REP(j,,m-)
{
int w=getint(),fr=(i<<)*(m-)+j,to=fr-m+;
add_edge(fr,to,w),add_edge(to,fr,w);
}
REP(i,,m-)
{
int w=getint(),tmp=((n<<)-)*(m-)+i;
add_edge(,tmp,w),add_edge(tmp,,w);
}
REP(i,,n-)
{
int w=getint(),tmp=(i<<)*(m-)+m;
add_edge(,tmp,w),add_edge(tmp,,w);
REP(j,,m-)
{
int fr=(i<<)*(m-)+j-,to=fr+m;
add_edge(fr,to,w=getint()),add_edge(to,fr,w);
}
tmp=(m-)*(i<<|),w=getint(),
add_edge(tmp,nm+,w),add_edge(nm+,tmp,w);
}
REP(i,,n-) REP(j,,m-)
{
int w=getint(),fr=(i<<)*(m-)+j,to=fr+m-;
add_edge(fr,to,w),add_edge(to,fr,w);
}
printf("%d\n",SPFA(,nm+));
return ;
}

bzoj1001题解的更多相关文章

  1. 【bzoj1001】【最短路】【对偶图】【最大流转最小割】狼抓兔子题解

    [BZOJ1001]狼抓兔子 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 18872  Solved ...

  2. 【题解】狼抓兔子—BZOJ1001。

    (胡扯时间)今天炒鸡无聊就打算BZOJ开始从第一道题开始顺着打,这样未来一段时间内也就有事干了.结果发现A+B切掉后就遭遇了一个"小小"的瓶颈(真不友好. 好了说题说题.看题第一眼 ...

  3. BZOJ1001 洛谷4001 [BJOI2006]狼抓兔子 题解

    题目 这个题目有多种解法,这个题也是一个比较经典的题了,正是因为他的多样的做法,这个题主要难在建图和优化,因为这是一个网格图,所以spfa肯定过不去,所以用最短路解法的话,只能用dij,而网络流也是要 ...

  4. BZOJ1001 狼抓兔子 题解

    裸的最小割,转化成最大流即可. #include <bits/stdc++.h> int n,m; int S,T; int mincost; int head[6001000],tot= ...

  5. 【BZOJ1001】狼抓兔子(网络流)

    [BZOJ1001]狼抓兔子(网络流) 题面 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨, ...

  6. BZOJ1001 [BeiJing2006]狼抓兔子 最小割 对偶图 最短路

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686871.html 题目传送门 - BZOJ1001 题意 长成上面那样的网格图求最小割. $n,m\leq ...

  7. 【BZOJ1001】[BeiJing2006]狼抓兔子 对偶图最短路

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

  8. 【BZOJ1001】狼抓兔子(平面图转对偶图,最短路)

    [BZOJ1001]狼抓兔子(平面图转对偶图,最短路) 题面 BZOJ 洛谷 题解 这题用最小割可以直接做 今天再学习了一下平面图转对偶图的做法 大致的思路如下: 1.将源点到汇点中再补一条不与任何线 ...

  9. BZOJ1001/LG4001 「ICPC Beijing2006」狼抓兔子 平面图最小割转对偶图最短路

    问题描述 BZOJ1001 LG4001 题解 平面图最小割=对偶图最短路 假设起点和终点间有和其他边都不相交的一条虚边. 如图,平面图的若干条边将一个平面划分为若干个图形,每个图形就是对偶图中的一个 ...

随机推荐

  1. web.xml中配置——加载spring容器

    <context-param> <param-name>contextConfigLocation</param-name> <param-value> ...

  2. 详解 MySQL int 类型的长度值问题

    以下是每个整数类型的存储和范围 (来自 mysql 手册)

  3. JS判断浏览器类型的方法总结(IE firefox chrome opera safari)

    JS判断浏览器类型的方法总结,可判别当前客户端所使用的浏览器是ie,firefox,safari,chrome或者是opera,另外js可以精确判断到ie浏览器的版本,依然直接上代码,需要的朋友可按照 ...

  4. XML解析方式有哪些?

    1.DOM:要求解析器吧整个XML文档装载到内存,并解析成一个Document对象. (1).优点:元素与元素之间保留结构关系,故可以进行增删改查操作. (2).缺点:XML文档过大,可能出现内存溢出 ...

  5. 牛客 某练习赛 Data Structure

    Data Structure 题目描述 将一个非负整数序列划分为 \(K\) 段,分别计算出各段中的整数按位或的结果,然后再把这些结果按位与起来得到一个最终结果,把这个最终结果定义为这个序列的一个 \ ...

  6. HDU 4866 Shooting 题解:主席树

    这题的主要的坑点就是他给你的射击目标有重合的部分,如果你向这些重合的部分射击的话要考虑两种情况: 射击目标数量 ≥ 重合数量 : 全加上 射击目标数量 ≤ 重合数量 : 只加距离*射击目标数量 然而这 ...

  7. 常用的HTTP请求头与响应头

    HTTP消息头是指,在超文本传输协议( Hypertext Transfer Protocol ,HTTP)的请求和响应消息中,协议头部分的那些组件.HTTP消息头用来准确描述正在获取的资源.服务器或 ...

  8. vue 笔记,ref 及 $event 事件对象

    本文仅用作简单记录 ref : 在标签上添加 ref = “name” ,表示获取当前元素节点 <input type="text" ref="info" ...

  9. hbase启动的时候报:cat: /home/hadoop/hbase-0.94.6-cdh4.5.0/target/cached_classpath.txt: 没有那个文件或目录

    启动hbase的时候: -cdh4.5.0/bin$ hbase shell cat: /home/hadoop/hbase--cdh4.5.0/target/cached_classpath.txt ...

  10. leetcode.字符串.242有效的字母异位词-Java

    1. 具体题目 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 注:判断两个字符串包含的字母是否完全一样. 示例 1: 输入: s = "anagram&q ...