BZOJ 1001 [BeiJing2006] 狼抓兔子
来源:互联网 发布:手机查看淘宝价格走势 编辑:程序博客网 时间:2024/06/16 05:01
Description
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
左上角点为(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只狼,
才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
狼的数量要最小。因为狼还要去找喜羊羊麻烦.
Input
第一行为N,M.表示网格的大小,N,M均小于等于1000.
接下来分三部分
第一部分共N行,每行M-1个数,表示横向道路的权值.
第二部分共N-1行,每行M个数,表示纵向道路的权值.
第三部分共N-1行,每行M-1个数,表示斜向道路的权值.
输入文件保证不超过10M
Output
输出一个整数,表示参与伏击的狼的最小数量.
Sample Input
3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
Sample Output
14
HINT
2015.4.16新加数据一组,可能会卡掉从前可以过的程序。
Source
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
最小割转最短路~
这道题直接用最小割会T得很惨(经验之谈)~
(如果好奇T了的程序长什么样,在这篇博文的最后面有~)
利用了对偶图的性质(并不知道是什么性质),可以把这道题中的图转化一下,再跑最短路。
具体做法是这样:
(红线是转成的图~图上有水印,我就不标来源了~)
新建一个源点,一个汇点,然后把每个由边围成的最小三角形看做点(我的标号是以每个方块左上角的点(u,v)为依据的,每个方块又被分为两个三角形,左下角的id是1,右上角的id是2,所以标号就是((u-1)*(m-1)+v-1)*2+id,建议画个图~),两个三角形之间连的边权值是两个三角形的公共边权值。然后SPFA就可以了~
注意n==1||m==1的情况要特判!不判的话WA到飞起啊!
#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;#define d(u,v,id) (((u-1)*(m-1)+v-1)*2+id)int n,m,x,S,T,fi[2000005],w[6000005],ne[6000005],v[6000005],cnt,dis[2000005];bool b[2000005];void add(int u,int vv,int val){w[++cnt]=vv;ne[cnt]=fi[u];fi[u]=cnt;v[cnt]=val;w[++cnt]=u;ne[cnt]=fi[vv];fi[vv]=cnt;v[cnt]=val;}int spfa(){queue<int> q;memset(dis,127/3,sizeof(dis));dis[S]=0;b[S]=1;q.push(S);while(!q.empty()){int k=q.front();q.pop();b[k]=0;for(int i=fi[k];i;i=ne[i]) if(dis[w[i]]>dis[k]+v[i]) { dis[w[i]]=dis[k]+v[i]; if(!b[w[i]]) { b[w[i]]=1;q.push(w[i]);} }}return dis[T];}int main(){scanf("%d%d",&n,&m);T=2*(n-1)*(m-1)+1;if(n==1 || m==1){if(n>m) swap(n,m);int ans=999999999;for(int i=1;i<m;i++) scanf("%d",&x),ans=min(x,ans);printf("%d\n",ans);return 0;}for(int i=1;i<m;i++) scanf("%d",&x),add(S,d(1,i,2),x);for(int i=2;i<n;i++) for(int j=1;j<m;j++) scanf("%d",&x),add(d(i-1,j,1),d(i,j,2),x);for(int i=1;i<m;i++) scanf("%d",&x),add(d(n-1,i,1),T,x);for(int i=1;i<n;i++) for(int j=1;j<=m;j++) { scanf("%d",&x); if(j==1) add(d(i,j,1),T,x); else if(j==m) add(S,d(i,j-1,2),x); else add(d(i,j-1,2),d(i,j,1),x); }for(int i=1;i<n;i++) for(int j=1;j<m;j++) scanf("%d",&x),add(d(i,j,1),d(i,j,2),x);printf("%d\n",spfa());return 0;}
T了的最小割:
#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;#define d(u,v) (u-1)*m+vint n,m,t,fi[1000001],w[6000001],ne[6000001],v[6000001],val,cnt,ans,dis[1000001];void add(int u,int vv,int val){w[++cnt]=vv;ne[cnt]=fi[u];fi[u]=cnt;v[cnt]=val;w[++cnt]=u;ne[cnt]=fi[vv];fi[vv]=cnt;v[cnt]=val;}bool bfs(){queue<int> q;q.push(1);memset(dis,-1,sizeof(dis));dis[1]=0;while(!q.empty()){int k=q.front();q.pop();for(int i=fi[k];i;i=ne[i]) if(v[i]>0 && dis[w[i]]==-1) { dis[w[i]]=dis[k]+1;q.push(w[i]); }}if(dis[t]==-1) return 0;return 1;}int findd(int u,int vv){if(u==t) return vv;int kkz,tot=0;for(int i=fi[u];i;i=ne[i]) if(v[i]>0 && dis[w[i]]==dis[u]+1 && (kkz=findd(w[i],min(vv-tot,v[i])))) { v[i]-=kkz;v[i^1]+=kkz;tot+=kkz; if(tot==vv) return tot; }if(!tot) dis[u]=-1;return tot;}int main(){scanf("%d%d",&n,&m);cnt=1;t=d(n,m);for(int i=1;i<=n;i++) for(int j=1;j<m;j++) scanf("%d",&val),add(d(i,j),d(i,j+1),val);for(int i=1;i<n;i++) for(int j=1;j<=m;j++) scanf("%d",&val),add(d(i,j),d(i+1,j),val);for(int i=1;i<n;i++) for(int j=1;j<m;j++) scanf("%d",&val),add(d(i,j),d(i+1,j+1),val);while(bfs()) ans+=findd(1,999999999);printf("%d\n",ans);return 0;}
1 0
- bzoj 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001: [BeiJing2006] 狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001 [BeiJing2006]狼抓兔子
- BZOJ-1001 [BeiJing2006]狼抓兔子
- [BZOJ]1001: [BeiJing2006]狼抓兔子
- 【BZOJ】1001: [BeiJing2006]狼抓兔子
- BZOJ 1001 [BeiJing2006] 狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- bzoj 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001 [BeiJing2006]狼抓兔子
- BZOJ 1001: [BeiJing2006]狼抓兔子
- 【bzoj 1001】 狼抓兔子 [BeiJing2006]
- dos 文件同步
- warning LNK4099: PDB 原因及解决方案
- TX1刷机ubuntu14.04 以及安装ros indigo
- .NET 第六章 上机二 实现工作汇报
- 解决安装多个版本的JDK后eclipse无法启动的问题
- BZOJ 1001 [BeiJing2006] 狼抓兔子
- 深度学习在spark平台上进入生产环境
- Struts2常用拦截器
- LeetCode-374. Guess Number Higher or Lower
- SqlSession执行
- 深入理解Activity启动流程(二)–Activity启动相关类的类图
- 什么是 ANR?
- Linux学习总结——linux I/O进阶
- mysql 5.7以上date/datetime默认值问题