题目描述 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);
}

wikioi3052 多米诺的更多相关文章

  1. 多米诺(codevs 3052)

    题目描述 Description 一个矩形可以划分成M*N个小正方形,其中有一些小正方形不能使用.一个多米诺骨牌占用两个相邻的小正方形.试问整个区域内最多可以不重叠地放多少个多米诺骨牌且不占用任何一个 ...

  2. [CareerCup] 6.2 Dominos on Chess Board 棋盘上的多米诺

    6.2 There is an 8x8 chess board in which two diagonally opposite corners have been cut off. You are ...

  3. 【Tsinghua OJ】多米诺骨牌(domino)问题

    (domino.c/cpp)[问题描述] 小牛牛对多米诺骨牌有很大兴趣,然而她的骨牌比较特别,只有黑色和白色的两种.她觉 得如果存在连续三个骨牌是同一种颜色,那么这个骨牌排列便是不美观的.现在她有n个 ...

  4. 省选训练赛第4场D题(多米诺骨牌)

    题目来自FZU2163 多米诺骨牌 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description Vasya很喜欢排多米诺 ...

  5. 【01背包】洛谷P1282多米诺骨牌

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

  6. 多米诺骨牌放置问题(状压DP)

    例题: 最近小A遇到了一个很有趣的问题: 现在有一个\(n\times m\)规格的桌面,我们希望用\(1 \times 2\)规格的多米诺骨牌将其覆盖. 例如,对于一个\(10 \times 11\ ...

  7. P1282 多米诺骨牌 (背包变形问题)

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...

  8. [LeetCode] Push Dominoes 推多米诺骨牌

    There are N dominoes in a line, and we place each domino vertically upright. In the beginning, we si ...

  9. [Swift]LeetCode790. 多米诺和托米诺平铺 | Domino and Tromino Tiling

    We have two types of tiles: a 2x1 domino shape, and an "L" tromino shape. These shapes may ...

随机推荐

  1. ubuntu下安装pdo扩展

    ubuntu下安装好LAMP后默认情况没有安装mysql_pdo扩展,以下是安装 步聚,在终端输入以下命令 1.pecl search pdo 2.sudo pecl install pdo 当出现E ...

  2. JS-Date日期内置对象

    1.基本用法 <script> var date = new Date(); document.write(date+"<br/>");//获取具体时间 d ...

  3. [深入React] 6.组件

    组件是react的大杀器,超出其他框架几百里 react 组件和dom一样也是树状结构,只能由上而下传递变量(或者调用),不可以兄弟间或者更远的发生关系,为的就是简单,而且工作的很好. 每个组件有自己 ...

  4. 【C#基础】HTTP发送POST二进制数据

    //postdata为数组的请求方式 public byte[] POST(string Url, byte[] byteRequest) { byte[] responsebody; HttpWeb ...

  5. nexus4/5/6/7/9/10设备谷歌安卓5.1.1系统底包下载

    https://developers.google.com/android/nexus/images http://www.inexus.co/thread-18488-1-1.html

  6. 一个封装HTTP请求的函数(C++)

    这里封装了HTTP请求的,支持GET与POST,并支持各种参数组合,调用方式很简单使用DEVWEB::WebRequest(string(“http://www.luaie.com/”),ret);就 ...

  7. 函数返回char* 的解决方案

    在C语言中,自动变量在堆栈中分配内存.当包含自动变量的函数或代码块退出时,它们所占用的内存便被回收,它们的内容肯定会被下一个所调用的函数覆盖.这一切取决于堆栈中先前的自动变量位于何处,活动函数声明了什 ...

  8. Java开发者易犯错误Top10

    本文总结了Java开发者经常会犯的前十种错误列表. Top1. 数组转换为数组列表 将数组转换为数组列表,开发者经常会这样做: List<String> list = Arrays.asL ...

  9. linux-ln命令

    ln分为软链接和硬链接 1.软连接 -s   ln -s /mnt/hgfs/SHARE hvshare2 相当于在当前目录下新建一个名为hvshare2的快捷方式指向/mnt/hgfs/SHARE路 ...

  10. 【转】NSHashtable and NSMaptable

    本文转自Nidom的博客,原文:<NSHashtable & NSMaptable>   NSSet, NSDictionary, NSArray是Foundation框架关于集合 ...