ZJOI2009 狼和羊的故事
来源:互联网 发布:c语言 if语句 字符串 编辑:程序博客网 时间:2024/04/29 08:13
题目大意
“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。
Input
文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。
Output
文件中仅包含一个整数ans,代表篱笆的最短长度。
Sample Input
2 2
2 2
1 1
Sample Output
2
数据范围
10%的数据
30%的数据
100%的数据
思路分析
这道题目不难想到是一道最小割的题。我们要使得羊和狼不存在路,就可以转换为羊集和狼集不从在通路,那么这样就转换成了一个最小割的题目了。
连边方法
参考代码
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define maxn 105#define oo 100000000using namespace std;const int fx[4][2]={{-1,0},{1,0},{0,1},{0,-1}};int a[maxn*maxn],head[maxn*maxn],t[maxn*maxn*10],next[maxn*maxn*10],v[maxn*maxn*10],sum;int n,m;int vh[maxn*maxn],pre[maxn*maxn],his[maxn*maxn],di[maxn*maxn],dis[maxn*maxn];void insert(int x,int y,int z){ t[++sum]=y; v[sum]=z; next[sum]=head[x]; head[x]=sum;}int main(){ scanf("%d%d",&n,&m); fo(i,1,n*m) scanf("%d",&a[i]); sum=1; fo(i,1,n) fo(j,1,m){ int w=(i-1)*m+j; if (a[w]==1){ insert(0,w,oo); insert(w,0,0); fo(k,0,3){ int xx=i+fx[k][0],yy=j+fx[k][1]; if (xx<=0||yy<=0||xx>n||yy>m||a[(xx-1)*m+yy]==1) continue; insert(w,(xx-1)*m+yy,1); insert((xx-1)*m+yy,w,0); } } else if (a[w]==0){ fo(k,0,3){ int xx=i+fx[k][0],yy=j+fx[k][1]; if (xx<=0||yy<=0||xx>n||yy>m||a[(xx-1)*m+yy]==1) continue; insert(w,(xx-1)*m+yy,1); insert((xx-1)*m+yy,w,0); } } else { insert(w,n*m+1,oo); insert(n*m+1,w,0); } } bool p; int tot=n*m+2,x=0,aug=oo,ans=0; vh[0]=tot; while (dis[0]<tot){ p=0; his[x]=aug; for(int tmp=di[x];tmp;tmp=next[tmp]){ if (v[tmp]&&dis[t[tmp]]+1==dis[x]){ p=1; di[x]=tmp; pre[t[tmp]]=x; aug=min(aug,v[tmp]); x=t[tmp]; if (x==n*m+1){ ans+=aug; while (x) { int last=pre[x]; v[di[last]]-=aug; v[di[last] ^ 1]+=aug; x=last; } } break; } } if (p) continue; int k,min=tot; for(int tmp=head[x];tmp;tmp=next[tmp]) if (dis[t[tmp]]<min&&v[tmp]) min=dis[t[tmp]],k=tmp; if (--vh[dis[x]]==0) break; vh[++min]++; dis[x]=min; di[x]=k; if (x){ x=pre[x]; aug=his[x]; } } printf("%d\n",ans); return 0;}
0 0
- 【ZJOI2009】狼和羊的故事
- BZOJ [ZJOI2009]狼和羊的故事
- 1412: [ZJOI2009]狼和羊的故事
- ZJOI2009 狼和羊的故事
- 【ZJOI2009】狼和羊的故事
- 1412: [ZJOI2009]狼和羊的故事
- 【ZJOI2009】[JZOJ1637] 狼和羊的故事
- 【JZOJ1637】【ZJOI2009】狼和羊的故事
- 【ZJOI2009】狼和羊的故事
- BZOJ1412: [ZJOI2009]狼和羊的故事
- 1412: [ZJOI2009]狼和羊的故事
- bzoj1412: [ZJOI2009]狼和羊的故事
- [bzoj1934]: [ZJOI2009]狼和羊的故事
- bzoj1412 [ZJOI2009]狼和羊的故事
- bzoj1412: [ZJOI2009]狼和羊的故事
- BZOJ1412: [ZJOI2009]狼和羊的故事
- [jzoj1637]【ZJOI2009】狼和羊的故事
- BZOJ1412 [ZJOI2009]狼和羊的故事
- 融入设计模式思想的C教学,借助opencv(一)
- 好的习惯很重要,嘿嘿
- 背景图自适应
- 简说期望类问题的解法
- 什么是接口
- ZJOI2009 狼和羊的故事
- PAT1043 输出PATest
- Android中的音乐播放
- 图片拉伸
- 全局获取Context的技巧
- JAVA中注解的简单使用
- 【20150911】NOIP模拟套题02 day1 题解 & 总结
- jd -eclipse 放到eclipse 中进行自动反编译
- 关于iOS中 __bridge,__bridge_transfer和__bridge_retained的使用