多米诺(codevs 3052)

题目描述 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。

/*
  二分图匹配问题
  问题是从一坨方格关系中选出尽量多的关系,使每个方格只选一次。
  通过观察我们可以发现,横坐标加纵坐标是偶数的方格只能和奇数的方格匹配,所以就变成了二分图的匹配问题。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 51
using namespace std;
int g[N][N],n,m,p,head[N*N],cnt;
int used[N*N],belong[N*N];
struct node{
    int v,pre;
};node e[N*N*2];
void add(int x,int y){
    e[++cnt].v=y;
    e[cnt].pre=head[x];
    head[x]=cnt;
}
bool find(int i){
    for(int j=head[i];j;j=e[j].pre){
        if(!used[e[j].v]){
            used[e[j].v]=1;
            if(!belong[e[j].v]||find(belong[e[j].v])){
                belong[e[j].v]=i;
                return true;
            }
        }
    }
    return false;
}
int main(){
    freopen("jh.in","r",stdin);
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=p;i++){
        int x,y;scanf("%d%d",&x,&y);
        g[x][y]=1;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if((i+j&1)||g[i][j])continue;
            if(!g[i-1][j]&&i-1>=1)add((i-1)*m+j,(i-2)*m+j);
            if(!g[i+1][j]&&i+1<=n)add((i-1)*m+j,i*m+j);
            if(!g[i][j-1]&&j-1>=1)add((i-1)*m+j,(i-1)*m+j-1);
            if(!g[i][j+1]&&j+1<=m)add((i-1)*m+j,(i-1)*m+j+1);
        }
    }
    int tot=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if((i+j&1)||g[i][j])continue;
            memset(used,0,sizeof(used));
            if(find((i-1)*m+j))tot++;
        }
    }
    printf("%d",tot);
    return 0;
}
时间: 2024-10-26 21:01:04

多米诺(codevs 3052)的相关文章

codevs 3052 多米诺 二分图匹配

/*codevs 3052 二分图匹配 把矩阵分两批 黑和白 且黑白不相交 这就构成了二分图的两部分 然后求最大匹配*/ #include<cstdio> #include<cstring> #define maxn 5010 using namespace std; int n,m,k,num,head[maxn],match[maxn],ans; int g[51][51],f[maxn],Color[51][51]; struct node{ int v,pre; }e[ma

POJ 1135 Domino Effect(最短路 多米诺骨牌)

题意 题目描述: 你知道多米诺骨牌除了用来玩多米诺骨牌游戏外,还有其他用途吗?多米诺骨牌游戏:取一 些多米诺骨牌,竖着排成连续的一行,两张骨牌之间只有很短的空隙.如果排列得很好,当你推 倒第 1张骨牌,会使其他骨牌连续地倒下(这就是短语"多米诺效应"的由来). 然而当骨牌数量很少时,这种玩法就没多大意思了,所以一些人在 80 年代早期开创了另一个 极端的多米诺骨牌游戏:用上百万张不同颜色.不同材料的骨牌拼成一幅复杂的图案.他们开创 了一种流行的艺术.在这种骨牌游戏中,通常有多行骨牌同时

棋盘的多米诺覆盖:Dimer Lattice Model,Pfaff 多项式,Kasteleyn 定理

这次来介绍计数组合学里面一个经典的问题:Dimer Lattice Model.问题是这样的:一个有 64 个方格的国际象棋棋盘,有多少种不同的多米诺骨牌覆盖?这里的覆盖是指不重复不遗漏地盖住整个棋盘. 下图是一种可能的覆盖方式(图片来自 Wiki 百科): 这个问题的答案是 12988816,非常大的一个数字,绝对不是一个一个数出来的.1961 年德国物理学家 Kasteleyn 借助于线性代数中的一个结论首先解决了这个问题,我们接下来就介绍他的方法. ~~~~~~~~~~~~~~~~~~~~

洛谷 P1282 多米诺骨牌

题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2.每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置. 编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小. 对于图中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0. 输入输出格式 输入格式: 输入文件的第一行是一个正

鲁米诺反应

鲁米诺(luminol),又名发光氨.一种在犯罪现场检测肉眼无法观察到的血液,可以显现出极微量的血迹形态(潜血反应).化学名称为3-氨基苯二甲酰肼.常温下是一种黄色晶体或者米黄色粉末,是一种比较稳定的人工合成的有机化合物.化学式为C8H7N3O2,溶液显强酸性,对眼睛.皮肤.呼吸道有一定刺激作用.由于血红蛋白含有铁,而铁能催化过氧化氢的分解,让过氧化氢变成水和单氧,单氧再氧化鲁米诺让它发光.所以鲁米诺广泛应用于刑事侦查.生物工程.化学示踪等领域.

luogu P1282 多米诺骨牌

题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2.每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置. 编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小. 对于图中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0. 输入输出格式 输入格式: 输入文件的第一行是一个正

poj 1717==洛谷P1282 多米诺骨牌

Dominoes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6571   Accepted: 2178 Description A domino is a flat, thumbsized tile, the face of which is divided into two squares, each left blank or bearing from one to six dots. There is a ro

AOJ 589.多米诺

Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MBTotal Submission: 34   Submission Accepted: 12 Description 有一个n*m的网格,用一些2*1的多米诺去填充.有以下规则:1.每一个多米诺必须完整覆盖两个格子2.多米诺之间不能重叠3.多米诺不能超过网格边界4.摆放多米诺时可以旋转,但是不能斜着摆放问最多可以用多少个多米诺去覆盖网格. Input 一个整数

多米诺翻转

我们的问题从一张 $8\times8$ 的国际象棋棋盘开始.棋盘的一个铺砌 $T$,是指用若干$1\times2$ 的多米诺骨牌不重叠不遗漏地盖住棋盘的一种方法.显然在一个铺砌 $T$ 中,每个骨牌恰好盖住一对相邻的方格,因此总共需要 32 张骨牌. 任给一个棋盘的铺砌 $T$,考虑这样一种局部的操作:选择 $T$ 中一个 $2\times2$ 的正方形,它包含一对平行的多米诺骨牌,然后将这对骨牌翻转 90 度,即把一对水平并排放置的骨牌变成垂直并排放置的(或者反之).这样一个操作叫做翻转(fi