bzoj1001题解
【解题思路】
显然,这题的答案是这个网格图的最小割。根据最大流-最小割定理,我们可以用网络流算法来求其最小割,时间复杂度最小为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题解的更多相关文章
- 【bzoj1001】【最短路】【对偶图】【最大流转最小割】狼抓兔子题解
[BZOJ1001]狼抓兔子 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 18872 Solved ...
- 【题解】狼抓兔子—BZOJ1001。
(胡扯时间)今天炒鸡无聊就打算BZOJ开始从第一道题开始顺着打,这样未来一段时间内也就有事干了.结果发现A+B切掉后就遭遇了一个"小小"的瓶颈(真不友好. 好了说题说题.看题第一眼 ...
- BZOJ1001 洛谷4001 [BJOI2006]狼抓兔子 题解
题目 这个题目有多种解法,这个题也是一个比较经典的题了,正是因为他的多样的做法,这个题主要难在建图和优化,因为这是一个网格图,所以spfa肯定过不去,所以用最短路解法的话,只能用dij,而网络流也是要 ...
- BZOJ1001 狼抓兔子 题解
裸的最小割,转化成最大流即可. #include <bits/stdc++.h> int n,m; int S,T; int mincost; int head[6001000],tot= ...
- 【BZOJ1001】狼抓兔子(网络流)
[BZOJ1001]狼抓兔子(网络流) 题面 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨, ...
- BZOJ1001 [BeiJing2006]狼抓兔子 最小割 对偶图 最短路
原文链接http://www.cnblogs.com/zhouzhendong/p/8686871.html 题目传送门 - BZOJ1001 题意 长成上面那样的网格图求最小割. $n,m\leq ...
- 【BZOJ1001】[BeiJing2006]狼抓兔子 对偶图最短路
[BZOJ1001][BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子 ...
- 【BZOJ1001】狼抓兔子(平面图转对偶图,最短路)
[BZOJ1001]狼抓兔子(平面图转对偶图,最短路) 题面 BZOJ 洛谷 题解 这题用最小割可以直接做 今天再学习了一下平面图转对偶图的做法 大致的思路如下: 1.将源点到汇点中再补一条不与任何线 ...
- BZOJ1001/LG4001 「ICPC Beijing2006」狼抓兔子 平面图最小割转对偶图最短路
问题描述 BZOJ1001 LG4001 题解 平面图最小割=对偶图最短路 假设起点和终点间有和其他边都不相交的一条虚边. 如图,平面图的若干条边将一个平面划分为若干个图形,每个图形就是对偶图中的一个 ...
随机推荐
- IntelliJ IDEA 添加本地xsd文件
地址: http://code.alibabatech.com/schema/dubbo/dubbo.xsd
- linux挂载群辉的NFS共享文件夹
mount -t nfs 192.168.137.136:/volume1/NFSfile /NFSfile -o proto=tcp -o nolock df -h #查看挂载点
- Qt【Could not parse stylesheet of object 0x7f7990 】
查找自己所写的 setstylesheet(); 然后看里面的括号标点什么的有没有多余的,删除即可解决.
- Hbase速览
一.概述 理解为hadoop中的key-value存储,数据按列存储,基于HDFS和Zookeeper 1.应用 2.场景 适用场景: 存储格式:半结构化数据,结构化数据存储,Key-Value存储 ...
- 使用cordova,监听安卓机物理返回按键,实现退出程序的功能
在使用html5开发app时,并不能像Android原生那样调取手机自身的方法.而cordova正好弥补了html5这一缺陷. 一,在cordova中文网http://cordova.axuer.co ...
- 【架构】spring framework核心框架体系结构
Spring官方文档,用的版本为4.3.11版本. 一.引用官方文档 2.2.1核心集装箱 所述核心容器由以下部分组成spring-core, spring-beans,spring-context, ...
- 浅析阿里云API网关的产品架构和常见应用场景
自上世纪60年代计算机网络发展开始,API(Application Programming Interface )随之诞生,API即应用程序接口,是实现系统间衔接的桥梁.时至今日,API市场已经形成了 ...
- apue 第18章 终端I/O
终端I/O有两种不同的工作模式: (1)规范模式:输入以行单位进行处理,每个读请求也最多返回一行. (2)非规范模式:输入字符不装配成行. 终端设备是由通常位于内核中的终端驱动程序控制的.每个终端设备 ...
- 【C#技术】一篇文章搞掂:LLBL
公司代码速查 ParameterBase.CurrentUser.UserId ICustomerDeskDetailManager customerDeskDetailManager = Clien ...
- “今日头条杯”首届湖北省大学程序设计竞赛(网络同步赛 )--E. DoveCCL and Resistance
题目描述:链接点此 这套题的github地址(里面包含了数据,题解,现场排名):点此 链接:https://www.nowcoder.com/acm/contest/104/D来源:牛客网 题目描述 ...