BZOJ 1412 狼和羊的故事

首先,题目目的就是为了分割狼群和羊群,即建立超级源和超级汇求最小割从而转化成用网络流来处理。

如果没有空地,那么就是简单的二分图最大匹配,但是题中有空地的出现,所以需要在点与点之间建立双向边(不算后向弧),这样才能满足题意(我一开始挂到了这里)

理解透了还是很简单的

代码付上

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <queue>
  6 #include <iostream>
  7 using namespace std;
  8 #define N 105
  9 #define T 10005
 10 #define S 0
 11 int head[N*N],dep[N*N],cnt,n,m;
 12 struct node
 13 {
 14     int to,next,val;
 15 }e[N*N*N];
 16 inline void add(int x,int y,int z)
 17 {
 18     e[cnt].to=y;
 19     e[cnt].val=z;
 20     e[cnt].next=head[x];
 21     head[x]=cnt++;
 22     return ;
 23 }
 24 inline void insert(int x,int y,int z)
 25 {
 26     add(x,y,z);
 27     add(y,x,0);
 28     return ;
 29 }
 30 int bfs()
 31 {
 32     memset(dep,-1,sizeof(dep));
 33     queue <int >q;
 34     q.push(S);
 35     dep[S]=1;
 36     while(!q.empty())
 37     {
 38         int x=q.front();q.pop();
 39         for(int i=head[x];i!=-1;i=e[i].next)
 40         {
 41             int to1=e[i].to;
 42             if(dep[to1]==-1&&e[i].val)
 43             {
 44                 q.push(to1);
 45                 dep[to1]=dep[x]+1;
 46             }
 47         }
 48     }
 49     return dep[T]==-1?0:1;
 50 }
 51 int dfs(int x,int maxf)
 52 {
 53     if(!maxf)return 0;
 54     if(x==T)return maxf;
 55     int tflow=maxf,nowf;
 56     for(int i=head[x];i!=-1;i=e[i].next)
 57     {
 58         int to1=e[i].to;
 59         if(dep[to1]==dep[x]+1&&e[i].val&&dep[x]!=-1)
 60         {
 61             nowf=dfs(to1,min(e[i].val,tflow));
 62             if(!nowf)
 63             {
 64                 dep[to1]=-1;
 65                 continue;
 66             }
 67             tflow-=nowf;
 68             e[i].val-=nowf,e[i^1].val+=nowf;
 69             if(!tflow)break;
 70         }
 71     }
 72     dep[x]=-1;
 73     return maxf-tflow;
 74 }
 75 int map[N][N];
 76 int dx[4]={0,1,0,-1};
 77 int dy[4]={1,0,-1,0};
 78 int main()
 79 {
 80     memset(head,-1,sizeof(head));
 81     scanf("%d%d",&n,&m);
 82     for(int i=1;i<=n;i++)
 83     {
 84         for(int j=1;j<=m;j++)
 85         {
 86             int x;
 87             scanf("%d",&x);
 88             map[i][j]=x;
 89             if(x==2)insert((i-1)*m+j,T,1<<30);
 90             if(x==1)insert(S,(i-1)*m+j,1<<30);
 91         }
 92     }
 93     for(int i=1;i<=n;i++)
 94     {
 95         for(int j=1;j<=m;j++)
 96         {
 97             for(int k=0;k<4;k++)
 98             {
 99                 int ty=dx[k]+i,tx=dy[k]+j;
100                 if(ty==0||ty==n+1)continue;
101                 if(tx==0||tx==m+1)continue;
102                 int f=(i-1)*m+j,t=(ty-1)*m+tx;
103                 insert(f,t,1);
104             }
105         }
106     }
107     int ans=0;
108     while(bfs())
109     {
110         ans+=dfs(S,1<<30);
111     }
112     printf("%d\n",ans);
113     return 0;
114 }
View Code

 

posted @ 2018-02-16 23:03  Winniechen  阅读(282)  评论(0编辑  收藏  举报