题目描述 Description
一个矩形可以划分成M*N个小正方形,其中有一些小正方形不能使用。一个多米诺骨牌占用两个相邻的小正方形。试问整个区域内最多可以不重叠地放多少个多米诺骨牌且不占用任何一个被标记为无法使用的小正方形。
输入描述 Input Description
第一行有两个用空格隔开的正整数M和N。
第二行有一个正整数K,表示共有K个小正方形不能使用。输入数据保证K<=M*N。
以下K行每行有两个用空格隔开的数X和Y,表示第X行的第Y个小正方形不能使用。
输出描述 Output Description
输出最多能放多少个多米诺骨牌。
样例输入 Sample Input
3 3
2
1 1
2 2
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
对于30%的数据,M=1;
对于50%的数据,M<=2;
对于70%的数据,M<=3;
对于100%的数据,M<=50,N<=50。
考完期末考刷刷水题有益身心健康……
网络流……和1022的覆盖一样
先把所有点做黑白染色,S向所有可用的黑点连边,所有可用的白点向T连边,相邻可用的黑点和可用的白点连边,然后上dinic
#include<cstdio>
#include<cstring>
#define S 0
#define T 10000
#define inf 0x7fffffff
const int mx[4]={1,0,-1,0};
const int my[4]={0,1,0,-1};
inline int min(int a,int b)
{return a<b?a:b;}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,k,x,y,cnt=1,ans,t,w;
bool map[51][51];
inline bool mark(int x,int y)
{
return !(x<1||x>n||y<1||y>m);
}
int head[50001];
int h[50001];
int q[100001];
struct edge{
int to,v,next;
}e[50001];
inline void ins(int u,int v,int w)
{
e[++cnt].v=w;
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void insert(int u,int v,int w)
{
ins(u,v,w);
ins(v,u,0);
}
inline bool bfs()
{
memset(h,-1,sizeof(h));
t=0;w=1;
q[1]=S;h[S]=0;
while (t<w)
{
int now=q[++t];
for (int i=head[now];i;i=e[i].next)
{
if (e[i].v&&h[e[i].to]==-1)
{
q[++w]=e[i].to;
h[e[i].to]=h[now]+1;
}
}
}
if (h[T]==-1) return 0;
return 1;
}
inline int dfs(int x,int f)
{
if (x==T||f==0) return f;
int w,used=0;
for (int i=head[x];i;i=e[i].next)
{
if (h[e[i].to]==h[x]+1&&e[i].v)
{
w=f-used;
w=dfs(e[i].to,min(w,e[i].v));
e[i].v-=w;
e[i^1].v+=w;
used+=w;
}
}
if(!used) h[x]=-1;
return used;
}
inline void dinic()
{
while (bfs()) ans+=dfs(S,inf);
}
int main()
{
n=read();m=read();k=read();
for (int i=1;i<=k;i++)
{
x=read();y=read();
map[x][y]=1;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if(!map[i][j])
if ((i+j)&1)
{
insert(S,(i-1)*m+j,1);
for (int k=0;k<4;k++)
if (mark(i+mx[k],j+my[k]))
{
int nx=i+mx[k],ny=j+my[k];
insert((i-1)*m+j,(nx-1)*m+ny,1);
}
}else insert((i-1)*m+j,T,1);
dinic();
printf("%d",ans);
}