zoukankan      html  css  js  c++  java
  • 【BZOJ 1412】[ZJOI2009]狼和羊的故事

    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<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 using namespace std;
     6 const int inf=100000000,N=110;
     7 int fx[4]={0,0,1,-1},fy[4]={1,-1,0,0};
     8 struct ee{int to,next,f;}e[500001];
     9 int head[N*N],q[N*2*N],dis[N*N],a[N][N];
    10 int S,T,n,m,cnt=1,ans,w;
    11    
    12 void ins(int u,int v,int f){
    13     e[++cnt].to=v;e[cnt].f=f;e[cnt].next=head[u];head[u]=cnt;
    14     e[++cnt].to=u;e[cnt].f=0;e[cnt].next=head[v];head[v]=cnt;
    15 }
    16    
    17 bool bfs(){
    18     for (int i=1;i<=T;i++) dis[i]=inf;
    19     int h=0,t=1,now;
    20     q[1]=S;dis[S]=0;
    21     while(h!=t){
    22         now=q[++h];
    23         for (int i=head[now];i;i=e[i].next){
    24             int v=e[i].to;
    25             if (e[i].f&&dis[now]+1<dis[v]){
    26                 dis[v]=dis[now]+1;
    27                 if (v==T)return 1;
    28                 q[++t]=v;
    29             }
    30         }
    31     }
    32     if (dis[T]==inf) return 0; return 1;
    33 }
    34    
    35 int dinic(int now,int f){
    36     if (now==T) return f;
    37     int rest=f;
    38     for (int i=head[now];i;i=e[i].next){
    39         int v=e[i].to;
    40         if (e[i].f&&dis[v]==dis[now]+1&&rest){
    41             int t=dinic(v,min(rest,e[i].f));
    42             if (!t) dis[v]=0;
    43             e[i].f-=t;
    44             e[i^1].f+=t;
    45             rest-=t;
    46             //if(t) printf("%d %d %d
    ",now,v,e[i].f);
    47         }
    48     }
    49     return f-rest;
    50 }
    51 int main(){
    52     scanf("%d%d",&n,&m);
    53     S=0,T=n*m+1;
    54     for(int i=1;i<=n;i++)
    55         for(int j=1;j<=m;j++)
    56             scanf("%d",&a[i][j]);
    57     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) 
    58     if(a[i][j]==1) ins(S,(i-1)*m+j,inf);
    59     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
    60     if(a[i][j]==2) ins((i-1)*m+j,T,inf);
    61     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
    62         if(a[i][j]==1) {
    63             for(int ii=0;ii<4;ii++) {
    64                 int nx=i+fx[ii],ny=j+fy[ii];
    65                 if(nx>n||nx<1||ny>m||ny<1||a[nx][ny]==1) continue;
    66                 ins((i-1)*m+j,(nx-1)*m+ny,1);
    67             }
    68         }
    69         else if(a[i][j]==0){
    70             for(int ii=0;ii<4;ii++) {
    71                 int nx=i+fx[ii],ny=j+fy[ii];
    72                 if(nx>n||nx<1||ny>m||ny<1||a[nx][ny]==1) continue;
    73                 ins((i-1)*m+j,(nx-1)*m+ny,1);
    74             }
    75         }
    76     }
    77     while(bfs()) 
    78     ans+=dinic(S,inf);  
    79     printf("%d",ans);
    80 }
  • 相关阅读:
    助教观察记录5(10/21-11/3)
    助教观察记录4(10/07-10/20)
    助教观察记录3(9/23-10/06)
    助教观察记录1(9/5-9/15)
    2019年春季学期《C语言程序设计II》课程总结
    2020软件工程个人作业06——软件工程实践总结作业
    软件工程第二次作业
    2020软件工程作业3
    2020软件工程作业01
    神必高考数学题乱写
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5211718.html
Copyright © 2011-2022 走看看