zoukankan      html  css  js  c++  java
  • bzoj1412: [ZJOI2009]狼和羊的故事

    1412: [ZJOI2009]狼和羊的故事

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2614  Solved: 1335
    [Submit][Status][Discuss]

    Description

    “狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” 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%的数据 n,m≤3
    30%的数据 n,m≤20
    100%的数据 n,m≤100
     
     1 #include<bits/stdc++.h>
     2 #define N 10233
     3 #define inf 2147483647
     4 #define rep(i,l,r) for(int i=l;i<=r;i++)
     5 using namespace std;
     6 const int x[4]={1,-1,0,0};
     7 const int y[4]={0,0,1,-1};
     8 struct node{
     9     int to,next,w;
    10 }e[500000];
    11 int head[N],m,n,nx,ny,ans,dis[N],T,tot=1,cnt,num[110][110],mp[110][110];
    12 inline void ins(int u,int v,int w) {
    13      e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w;
    14 }
    15 inline void insert(int u,int v,int w) {
    16      ins(u,v,w); ins(v,u,0);
    17 }
    18 inline bool bfs(){
    19      memset(dis,-1,sizeof(dis)); queue<int>q; q.push(0); dis[0]=0;
    20      while(!q.empty()) {
    21           int x=q.front(); q.pop();
    22           for(int k=head[x];k;k=e[k].next) 
    23              if(dis[e[k].to]<0 && e[k].w>0) {
    24                    dis[e[k].to]=dis[x]+1; q.push(e[k].to);
    25              }
    26      }
    27      if(dis[T]>0) return 1;else return 0;
    28 }
    29 int find(int x,int low){
    30      if(x==T) return low;
    31      int delta=low,now;
    32      for(int k=head[x];k;k=e[k].next) 
    33        if(e[k].w>0 && dis[e[k].to]==dis[x]+1){ 
    34            now=find(e[k].to,min(e[k].w,delta));
    35            e[k].w-=now; e[k^1].w+=now;   delta-=now;
    36            if(!delta) return low;
    37         } 
    38      dis[x]=-1;
    39      return low-delta;
    40 }
    41 int main () {
    42      scanf("%d%d",&n,&m); T=n*m+1;
    43      rep(i,1,n) rep(j,1,m) num[i][j]=++cnt;
    44      rep(i,1,n) rep(j,1,m) {
    45          scanf("%d",&mp[i][j]);
    46          if(mp[i][j]==1) insert(0,num[i][j],inf);else if(mp[i][j]==2) insert(num[i][j],T,inf);
    47          for(int k=0;k<4;k++)
    48              {
    49                      int nowx=i+x[k],nowy=j+y[k];
    50                      if(nowx<1||nowx>n||nowy<1||nowy>m||mp[i][j]==2)continue;
    51                      if(mp[i][j]!=1||mp[nowx][nowy]!=1)
    52                      insert(num[i][j],num[nowx][nowy],1);
    53              }
    54      }
    55      while(bfs()) ans+=find(0,inf);
    56      printf("%d",ans);
    57 } 
    View Code

    从源点向所有狼连一条∞的边,从所有羊向汇点连一条∞的边,这样就能保证狼和羊都在不同的点集里。然后再从狼到相邻的羊和空地,空地到相邻的空地和羊连一条流量为1的边,最大流求最小割即可。

  • 相关阅读:
    iOS开发之--隐藏状态栏
    iOS开发之--iPhone X 适配:MJRefresh上拉加载适配
    iOS开发之--为UITextField监听数值变化的三种方法
    ios开发之--为父view上的子view添加阴影
    iOS开发之--在UIWindow上展示/移除一个View
    iOS开发之--Masonry多个平均布局
    CocoaPods更新过程中出现的坑及解决方法
    那些已成定局的人和事
    两个陌生人的对话
    好好写代码吧,没事别瞎B去创业!
  • 原文地址:https://www.cnblogs.com/Bloodline/p/5886241.html
Copyright © 2011-2022 走看看