题目描述 Description
有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地。如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积。
![](http://codevs.cn/media/image/problem/1022.jpg)
输入描述 Input Description
输入文件的第一行是两个整数N,M (1<=N,M<=100),第二行为一个整数K( K<=50),接下来的K行,每行两个整数X,Y表示K个水塘的行列位置。(1<=X<=N,1<=Y<=M)。
输出描述 Output Description
输出所覆盖的最大面积块(1×2面积算一块)。
样例输入 Sample Input
4 4
6
1 1
1 4
2 2
4 1
4 2
4 4
样例输出 Sample Output
4
网络流模板题
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; const int maxn=100*100+10,maxm=2*maxn; int n,m,k,S,T; bool pl[maxn]; int aa;char cc; int read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } struct Node{ int x,y,cap,flow; }node[2*maxm]; int cur[maxn]; int fir[maxn],nxt[2*maxm],e=1; void add(int x,int y,int z) { node[++e].x=x;node[e].y=y;node[e].cap=z; nxt[e]=fir[x];fir[x]=e; node[++e].x=y;node[e].y=x;node[e].cap=0; nxt[e]=fir[y];fir[y]=e; } int zz[maxn],dis[maxn],s=1,t=0; bool BFS() { memset(dis,-1,sizeof(dis)); dis[S]=0; s=1,t=0;zz[++t]=S; int x,y; while(s<=t) { x=zz[s];s++; for(y=fir[x];y;y=nxt[y]) { if(node[y].flow>=node[y].cap||dis[node[y].y]!=-1) continue; dis[node[y].y]=dis[x]+1; zz[++t]=node[y].y; } } return dis[T]!=-1; } int DFS(int pos,int maxf) { if(pos==T||!maxf) return maxf; int rs=0,now; for(int &y=cur[pos];y;y=nxt[y]) { if(node[y].flow>=node[y].cap||dis[node[y].y]!=dis[node[y].x]+1) continue; now=DFS(node[y].y,min(maxf,node[y].cap-node[y].flow)); node[y].flow+=now; node[y^1].flow-=now; rs+=now; maxf-=now; } if(!rs) dis[pos]=-1; return rs; } int Dinic() { int rs=0; while(BFS()) { memcpy(cur,fir,sizeof(fir)); rs+=DFS(S,0x3f3f3f3f); } return rs; } int main() { n=read();m=read();k=read(); int x,y; S=n*m+1;T=S+1; for(int i=1;i<=k;++i) { x=read();y=read(); pl[(x-1)*n+y]=1; } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { x=(i-1)*n+j; if(pl[x]) continue; if((i+j)%2==0) add(S,x,1); else add(x,T,1); if(i!=n&&!pl[x+n]) { if((i+j)%2==0) add(x,x+n,1); else add(x+n,x,1); } if(j!=m&&!pl[x+1]) { if((i+j)%2==0) add(x,x+1,1); else add(x+1,x,1); } } printf("%d",Dinic()); return 0; }