【BZOJ】【1412】【ZJOI2009】狼和羊的故事

网络流/最小割


  一开始我是将羊的区域看作连通块,狼的区域看作另一种连通块,S向每个羊连通块连一条无穷边,每个狼连通块向T连一条无穷边,连通块内部互相都是无穷边。其余是四连通的流量为1的边……然后WA了= =自己的数据和样例都过了……

  然后orz了一下Hzwer,改成对每个羊/狼都单独连一条无穷边,分界线/0点周围 连容量1的边……AC……

 

  1 /**************************************************************
  2     Problem: 1412
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:232 ms
  7     Memory:3224 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 1412
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 #define pb push_back
 21 using namespace std;
 22 inline int getint(){
 23     int v=0,sign=1; char ch=getchar();
 24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
 25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
 26     return v*sign;
 27 }
 28 const int N=21010,M=100000,INF=~0u>>2;
 29 const int fx[]={0,1,0,-1},
 30           fy[]={1,0,-1,0};
 31 typedef long long LL;
 32 /******************tamplate*********************/
 33 int n,m,a[110][110];
 34 struct edge{
 35     int from,to,v;
 36 };
 37 inline int pack(int i,int j){ return (i-1)*m+j; }
 38 struct Net{
 39     edge E[M];
 40     int head[N],next[M],cnt;
 41     bool vis[110][110];
 42     void add(int x,int y,int v){
 43         E[++cnt]=(edge){x,y,v};
 44         next[cnt]=head[x]; head[x]=cnt;
 45         E[++cnt]=(edge){y,x,0};
 46         next[cnt]=head[y]; head[y]=cnt;
 47     }
 48     int s,t,cur[N],d[N],Q[N];
 49     void bfs(int x,int y){
 50         rep(k,4){
 51             int tx=x+fx[k],ty=y+fy[k];
 52             if (a[tx][ty]==a[x][y] &&!a[x][y])
 53                 add(pack(x,y),pack(tx,ty),1);
 54             if (a[tx][ty]!=a[x][y]&&a[tx][ty]!=-1) 
 55                 add(pack(x,y),pack(tx,ty),1);
 56         }
 57     }
 58     void init(){
 59         n=getint();m=getint();
 60         cnt=1;
 61         s=0;t=n*m+1;
 62         int x,y;
 63         memset(a,-1,sizeof a);
 64         memset(vis,0,sizeof vis);
 65         F(i,1,n) F(j,1,m) a[i][j]=getint();
 66         F(i,1,n) F(j,1,m){
 67             bfs(i,j);
 68             if (a[i][j]==1) add(s,pack(i,j),INF);
 69             if (a[i][j]==2) add(pack(i,j),t,INF);
 70         }
 71     }
 72     bool mklevel(){
 73         memset(d,-1,sizeof d);
 74         d[s]=0;
 75         int l=0,r=-1;
 76         Q[++r]=s;
 77         while(l<=r){
 78             int x=Q[l++];
 79             for(int i=head[x];i;i=next[i])
 80                 if (d[E[i].to]==-1 && E[i].v){
 81                     d[E[i].to]=d[x]+1;
 82                     Q[++r]=E[i].to;
 83                 }
 84         }
 85         return d[t]!=-1;
 86     }
 87     int dfs(int x,int a){
 88         if (x==t||a==0) return a;
 89         int flow=0;
 90         for(int &i=cur[x];i && flow<a;i=next[i])
 91             if (d[E[i].to]==d[x]+1 && E[i].v){
 92                 int f=dfs(E[i].to,min(a-flow,E[i].v));
 93                 E[i].v-=f;
 94                 E[i^1].v+=f;
 95                 flow+=f;
 96             }
 97         if (!flow) d[x]=-1;
 98         return flow;
 99     }
100     int Dinic(){
101         int flow=0;
102         while(mklevel()){
103             F(i,s,t) cur[i]=head[i];
104             flow+=dfs(s,INF);
105         }
106         return flow;
107     }
108 }G1;
109 int main(){
110 #ifndef ONLINE_JUDGE
111     freopen("1412.in","r",stdin);
112     freopen("1412.out","w",stdout);
113 #endif
114     G1.init();
115     printf("%d\n",G1.Dinic());
116     return 0;
117 }
View Code

 

posted @ 2015-03-14 10:54  Tunix  阅读(180)  评论(0编辑  收藏  举报