[BZOJ1412][ZJOI2009]狼和羊的故事(最小割)
来源:互联网 发布:手机淘宝卖家从哪进 编辑:程序博客网 时间:2024/05/02 22:21
题目描述
传送门
题解
首先建立源汇,对于每一个为1的点s->i,对于每一个为2的点i->t,然后每个点向它的四周连边。
这样做的原因是无论如何狼和羊不能通过任何道路连通。
最小割即为答案。
代码
#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int max_n=105;const int max_N=1e4+5;const int max_m=2e5+5;const int max_e=max_m*2;const int INF=1e9;int n,m,a[max_n][max_n],N,maxflow;int tot,point[max_N],next[max_e],v[max_e],remain[max_e];int deep[max_N],last[max_N],num[max_N],cur[max_N];queue <int> q;inline void addedge(int x,int y,int cap){ ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=cap; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0;}inline void bfs(int t){ for (int i=1;i<=N;++i) deep[i]=N; deep[t]=0; while (!q.empty()) q.pop(); q.push(t); while (!q.empty()){ int now=q.front(); q.pop(); for (int i=point[now];i!=-1;i=next[i]) if (deep[v[i]]==N&&remain[i^1]){ deep[v[i]]=deep[now]+1; q.push(v[i]); } }}inline int addflow(int s,int t){ int now=t,ans=INF; while (now!=s){ ans=min(ans,remain[last[now]]); now=v[last[now]^1]; } now=t; while (now!=s){ remain[last[now]]-=ans; remain[last[now]^1]+=ans; now=v[last[now]^1]; } return ans;}inline void isap(int s,int t){ bfs(t); for (int i=1;i<=N;++i) ++num[deep[i]]; for (int i=1;i<=N;++i) cur[i]=point[i]; int now=s; while (deep[s]<N){ if (now==t){ maxflow+=addflow(s,t); now=s; } bool has_find=false; for (int i=cur[now];i!=-1;i=next[i]) if (deep[v[i]]+1==deep[now]&&remain[i]){ has_find=true; cur[now]=i; last[v[i]]=i; now=v[i]; break; } if (!has_find){ int minn=N-1; for (int i=point[now];i!=-1;i=next[i]) if (remain[i]) minn=min(minn,deep[v[i]]); if (!(--num[deep[now]])) break; ++num[deep[now]=minn+1]; cur[now]=point[now]; if (now!=s) now=v[last[now]^1]; } }}int main(){ tot=-1; memset(point,-1,sizeof(point)); memset(next,-1,sizeof(next)); scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) scanf("%d",&a[i][j]); N=n*m+2; for (int i=1;i<=n;++i) for (int j=1;j<=m;++j){ int num=(i-1)*m+j; if (a[i][j]==1) addedge(1,1+num,INF); else if (a[i][j]==2) addedge(1+num,N,INF); if (i!=1){ int num1=(i-2)*m+j; addedge(1+num,1+num1,1); } if (j!=1){ int num1=num-1; addedge(1+num,1+num1,1); } if (i!=n){ int num1=i*m+j; addedge(1+num,1+num1,1); } if (j!=m){ int num1=num+1; addedge(1+num,1+num1,1); } } isap(1,N); printf("%d\n",maxflow);}
总结
网络流再RE撞死算了。
0 0
- [BZOJ1412][ZJOI2009]狼和羊的故事(最小割)
- bzoj1412: [ZJOI2009]狼和羊的故事(最小割)
- bzoj1412 [ZJOI2009]狼和羊的故事(最小割)
- [BZOJ1412]ZJOI2009狼和羊的故事|最小割
- 【BZOJ1412】[ZJOI2009]狼和羊的故事【最小割】
- [ZJOI2009]BZOJ1412 狼和羊的故事-最小割
- BZOJ1412 [ZJOI2009]狼和羊的故事 最小割
- BZOJ1412 [ZJOI2009]狼和羊的故事 【最小割】
- [BZOJ1412] [ZJOI2009] 狼与羊的故事 (最小割)
- 最小割——BZOJ1412/Luogu2598 [ZJOI2009]狼和羊的故事
- BZOJ1412 / ZJOI2009 狼和羊的故事【网络流/最小割】
- BZOJ1412: [ZJOI2009]狼和羊的故事
- bzoj1412: [ZJOI2009]狼和羊的故事
- bzoj1412 [ZJOI2009]狼和羊的故事
- bzoj1412: [ZJOI2009]狼和羊的故事
- BZOJ1412: [ZJOI2009]狼和羊的故事
- BZOJ1412 [ZJOI2009]狼和羊的故事
- bzoj1412 [ZJOI2009]狼和羊的故事
- IOS开发-免证书调试(xcode7及以上)
- 指针数组的应用----判断参数是否与一个关键字列表中的任何单词匹配
- NanoPi2-S5P4418启动流程分析
- 递归算法-recursion
- UVALive 5181 Stamps and Envelope Size
- [BZOJ1412][ZJOI2009]狼和羊的故事(最小割)
- nyoj 712 探 寻 宝 藏(双线dp 第六届河南省程序设计大赛)
- 快速开发
- win7+python+matplotlib
- 老程序员应该记住的 5 件事
- java-jdbc开发基础
- Android中使用多张图片组成动画 AnimationDrawable
- uncaught typeerror cannot read property 'data' of undefined 报错原因
- 第8周项目2 用对象数组操作长方柱类