BZOJ 1001 狼抓兔子
2016-06-12 11:45
253 查看
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路
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只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.
思路:dinic网络流居然过了。。
据说正解是什么对偶图
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路
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只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.
思路:dinic网络流居然过了。。
据说正解是什么对偶图
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> int next[7000005],first[7000005],go[7000005],tot,val[7000005]; int dis[2000005],c[5000005],S,T,n,m,x,ans=0; int sta(int x,int y){ return (x-1)*m+y; } void insert(int x,int y,int z){ tot++; go[tot]=y; next[tot]=first[x]; first[x]=tot; val[tot]=z; tot++; go[tot]=x; next[tot]=first[y]; first[y]=tot; val[tot]=z; } bool bfs(){ int now,i; memset(dis,-1,sizeof dis); int h=0,t=1; c[1]=S; dis[S]=0; while (h<t){ h++; now=c[h]; for (int i=first[now];i;i=next[i]){ int pur=go[i]; if (val[i]&&dis[pur]<0){ c[++t]=pur; dis[pur]=dis[now]+1; } } } if (dis[T]==-1) return 0; return 1; } int dfs(int x,int f){ if (x==T) return f; int w,used=0; for (int i=first[x];i;i=next[i]){ int pur=go[i]; if (val[i]&&dis[pur]==dis[x]+1){ w=f-used; w=dfs(pur,std::min(w,val[i])); val[i]-=w; val[i+1]+=w; used+=w; if (used==f) return f; } } if (!used) dis[x]=-1; return used; } void dinic(){ while (bfs()) ans+=dfs(1,0x7fffffff); } int main(){ scanf("%d%d",&n,&m); S=1;T=sta(n,m); for (int i=1;i<=n;i++) for (int j=1;j<=m-1;j++){ scanf("%d",&x); insert(sta(i,j),sta(i,j+1),x); } for (int i=1;i<=n-1;i++) for (int j=1;j<=m;j++){ scanf("%d",&x); insert(sta(i,j),sta(i+1,j),x); } for (int i=1;i<=n-1;i++) for (int j=1;j<=m-1;j++){ scanf("%d",&x); insert(sta(i,j),sta(i+1,j+1),x); } dinic(); printf("%d",ans); }
相关文章推荐
- gulp常用模块gulp-sass,gulp-autoprefixer,gulp-wrap,browser-sync,gulp-rev,gulp-rev-collector模块解析
- nfs部署和优化
- Android 设置状态栏后adjustResize属性无效
- spring securit(五)
- Java中使用json与前台Ajax数据交互的方法
- 【Linux】硬盘格式化--mkfs
- R语言︱SNA-社会关系网络—igraph包(社群划分、画图)(三)
- 删除前JS弹出提示
- 浅谈cookie 和session 的区别
- 经验:修复双系统启动(win10和ubuntu16.04)
- redis 配置 linux
- 二维数组查找算法(C++)
- Windows下使用批处理实现启动关闭mysql
- Linux驱动中的异步通知
- 【.net 深呼吸】聊聊WCF服务返回XML或JSON格式数据
- JavaScript刷新页面,不重复提交
- 学术诚信与职业道德
- Fragment的使用
- CNTK安装
- vim 插件综述