bzoj1412: [ZJOI2009]狼和羊的故事(最小割)
首先,考虑只有狼和羊怎么办。我们把源点向所有羊连边,容$inf$,所有狼向汇点连边,容$inf$,然后羊向周围所有的狼连边,容$1$。那么,只要求一个割就能把狼和羊给分开,求一个最小割就是答案
那么考虑要怎么处理值为0的点
我们假设在网络流图中有这么一条边$S->羊->0->狼->T$,为了使狼和羊分开,我们可能把空地划分给狼或给羊,那么在图中求最小割时,会割开的只有$羊->0$或$0->狼$这两条边,分别对应两种情况。那么,只要对于每个空地,我们从羊向它连边,从它向狼连边,那么在前面的基础上跑一个最小割就是答案了
//minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int head[N],Next[M],ver[M],edge[M],tot=;
int cur[N],dep[N],id[][],mp[][];
int n,m,S,T;
queue<int> q;
int dx[]={,-,,},dy[]={,,,-};
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
}
bool bfs(){
memset(dep,-,sizeof(dep));
for(int i=S;i<=T;++i) cur[i]=head[i];
while(!q.empty()) q.pop();
q.push(S),dep[S]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(edge[i]&&dep[v]<){
dep[v]=dep[u]+,q.push(v);
if(v==T) return true;
}
}
}
return false;
}
int dfs(int u,int limit){
if(u==T||!limit) return limit;
int flow=,f;
for(int &i=cur[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=;
if(!limit) break;
}
}
return flow;
}
int dinic(){
int flow=;
while(bfs()) flow+=dfs(S,inf);
return flow;
}
void build(){
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
if(!mp[i][j]) continue;
(mp[i][j]&)?add(id[i][j],T,inf):add(S,id[i][j],inf);
}
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
if(mp[i][j]&) continue;
for(int k=;k<;++k){
int xx=i+dx[k],yy=j+dy[k];
if(xx<||xx>n||yy<||yy>m||(mp[xx][yy]&)) continue;
add(id[i][j],id[xx][yy],);
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
mp[i][j]=read(),id[i][j]=(i-)*m+j;
S=,T=n*m+;
build();
printf("%d\n",dinic());
return ;
}
bzoj1412: [ZJOI2009]狼和羊的故事(最小割)的更多相关文章
- BZOJ1412[ZJOI2009]狼和羊的故事——最小割
题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈 ...
- 【BZOJ1412】[ZJOI2009]狼和羊的故事 最小割
[BZOJ1412][ZJOI2009]狼和羊的故事 Description “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想: ...
- BZOJ 1412: [ZJOI2009]狼和羊的故事( 最小割 )
显然是最小割...把狼的领地连S, 羊的领地连T, 然后中间再连边, 跑最大流就OK了 -------------------------------------------------------- ...
- P2598 [ZJOI2009]狼和羊的故事(最小割)
P2598 [ZJOI2009]狼和羊的故事 说真的,要多练练网络流的题了,这么简单的网络流就看不出来... 题目要求我们要求将狼和羊分开,也就是最小割,(等等什么逻辑...头大....) 我们这样想 ...
- [ZJOI2009] 狼与羊的故事 - 最小割
给定一个\(N \times M\)方格矩阵,每个格子可在\(0,1,2\)中取值.要求在方格的边上进行划分,使得任意联通块内不同时包含\(1\)和\(2\)的格子. ________________ ...
- BZOJ1412 ZJOI2009 狼和羊的故事 【网络流-最小割】
BZOJ1412 ZJOI2009 狼和羊的故事 Description “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和 ...
- BZOJ1412 [ZJOI2009]狼和羊的故事 【最小割】
1412: [ZJOI2009]狼和羊的故事 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3454 Solved: 1733 [Submit][ ...
- bzoj1412: [ZJOI2009]狼和羊的故事
空地之间开始没有连然后一直WA...题意混乱...尴尬. #include<cstdio> #include<cstring> #include<iostream> ...
- LG2598/BZOJ1412 「ZJOI2009」狼和羊的故事 最小割
问题描述 LG2598 BZOJ1412 题解 看到要把狼和羊两个物种分开 自然想到最小割. 发现\((x,y)\)可以向上下左右走以获得贡献,所以建边:\((x,y),(x-1,y)\),\((x, ...
随机推荐
- python 链接sharepoint 2013 REST api
import requests,simplejson from requests_ntlm import HttpNtlmAuth p1 = requests.get("http://you ...
- jQuery购物数量数字加减运算效果
<a href="###" id="add" value="+">+</a> <input type=&quo ...
- poj3630 Phone List (trie树模板题)
Phone List Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26328 Accepted: 7938 Descr ...
- python中的enumerate()函数用法
enumerate函数用于遍历序列中的元素以及它们的下标,可以非常方便的遍历元素. 比如我在往excel中写数据时就用到了这个函数: data = [] data.append(('预约码', '车牌 ...
- linux命令学习笔记(39):grep 命令
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来. grep全称是Global Regular Expression Print,表示全局正则表 ...
- UVA12163 游戏
题目大意 现在有两个人在一个n个结点的有向图上玩一个双人游戏,保证图中无环和自圈.游戏的规则如下:1.初始的时候$i$号点有一个正权值$value_i$2.两名玩家依次操作,每个玩家在当前回合可以选择 ...
- ViewModel中C# Property自动添加OnPropertyChanged处理的小工具, 以及相应Python知识点
在做WPFMVVM中经常会遇到一些Model.ViewModel的属性添加添加私有字段和更改通知方法来支持Binding. 比如把: public class Test { public s ...
- category extension
1 category 分类,只能添加方法,添加的方法成为原来类的一部分,达到扩展类的目的,可以被子类继承 主要给没有源代码的类 添加方法,团队合作项目互不影响,不该动原有类的基础上添加方法 self ...
- NSDictionary和NSArray
// 字典里套数组 NSArray *array1 = @[@"huahau" , @"hehe"]; NSArray *array2 = @[@"x ...
- Apache Flume 1.6.0 发布,日志服务器
Apache Flume 1.6.0 发布,此版本现已提供下载: http://flume.apache.org/download.html 更新日志和文档: http://flume.apache. ...