的二分图poj2446

称号:

id=2446">poj2446

意甲冠军:给定一个m*n矩阵,在有些地方坑,然后1*2本文叠加,反复。可以把出了坑的地方其它所有覆盖的话输出YES,否则NO

分析:有一道二分图经典题目,当然难点还是建图,一直没有思路,早上来忽然想到能够用(i-1)*m+j 吧矩阵中每一个点转化为一个数,然后相邻连接起来建图,匈牙利,可是不知道为什么不正确?求大神解释、还是理解不够深。

非常多人都是按其奇偶性建图的,由于要用1*2的纸片覆盖,那么两个值(i+j)必定一个奇数一个偶数。然后分别给图中的奇数偶数点依次从1開始标号,相邻的按其标号建图。匈牙利、、比較高速。正解!

由于必定是一个奇数点相应一个相邻偶数点。那么仅仅要求随意奇数或偶数的最大匹配就能够了。经典的建图方法。

代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1200;
#define Del(x,y) memset(x,y,sizeof(x))
int map[N][N],link[N],vis[N],vlink[N];
int path[50][50];
int n,m,t,tmp1,tmp2;
bool dfs(int x)
{
    for(int i=1; i<tmp2; i++)
    {
        if(map[x][i]==1 && vis[i]==0)
        {
            vis[i]=1;
            if(link[i]==-1 || dfs(link[i]))
            {
                link[i]=x;
                return true;
            }
        }
    }
    return false;
}
void solve()
{
    int ans=0;
    Del(link,-1);
    Del(vlink,-1);
    for(int i=1; i<tmp1; i++)
    {
        Del(vis,0);
        if(dfs(i))
            ans++;
    }
    //printf("%d\n",ans);
    if(ans*2==(m*n-t))
        printf("YES\n");
    else
        printf("NO\n");
}
int main()
{
    //freopen("Input.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        Del(path,0);
        int x,y;
        scanf("%d",&t);

        for(int i=0; i<t; i++)
        {
            scanf("%d%d",&x,&y);
            path[y][x]=-1;
        }
        tmp1=1,tmp2=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(path[i][j]==0)
                {
                    if((i+j)%2==0)
                        path[i][j]=tmp1++;
                    else
                        path[i][j]=tmp2++;
                }
            }
        }
        Del(map,0);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(path[i][j]!=-1 && (i+j)%2==1)
                {
                    if(path[i-1][j]>=1)
                        map[path[i-1][j]][path[i][j]]=1;
                    if(path[i+1][j]>=1)
                        map[path[i+1][j]][path[i][j]]=1;
                    if(path[i][j-1]>=1)
                        map[path[i][j-1]][path[i][j]]=1;
                    if(path[i][j+1]>=1)
                        map[path[i][j+1]][path[i][j]]=1;
                }
            }
        }
        solve();
    }
    return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-10 10:03:00

的二分图poj2446的相关文章

二分图之poj2446

题目:poj2446 题意:给出一个m*n的矩阵,其中有的地方有坑,然后用1*2的纸片去覆盖图,纸片不能重复,能够把出了坑的地方其他全部覆盖的话输出YES,否则NO 分析:有一道二分图经典题目,当然难点还是建图,一直没有思路,早上来忽然想到可以用(i-1)*m+j 吧矩阵中每个点转化为一个数,然后相邻连接起来建图,匈牙利,但是不知道为什么不对?求大神解释.还是理解不够深. 很多人都是按其奇偶性建图的,因为要用1*2的纸片覆盖,那么两个值(i+j)必然一个奇数一个偶数,然后分别给图中的奇数偶数点依

POJ2446(二分图最大匹配)

Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16924   Accepted: 5284 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2

POJ2446 Chessboard【二分图最大匹配】

题目链接: http://poj.org/problem?id=2446 题目大意: 给一个N*M的矩阵,其中有K个地方有坑.告诉你这K个坑的位置,现在要用1*2的矩形板去覆盖 矩阵,不能覆盖有坑的地方.问:是否能把除了坑之外的地方全部覆盖掉,如果能,则输出"YES", 否则输出"NO". 思路: 考虑到矩形板的规格是1*2,则相邻位置的(i,j)和(x,y)必然是(i+j)为奇数的话,(x+y)则为偶数. (i+j)为偶数的话,(x+j)则为奇数.这样,就可以把图

[POJ2446] Chessboard(二分图最大匹配-匈牙利算法)

传送门 把所有非障碍的相邻格子彼此连一条边,然后求二分图最大匹配,看 tot * 2 + k 是否等于 n * m 即可. 但是连边不能重复,比如 a 格子 和 b 格子 相邻,不能 a 连 b ,b 也连 a. 所以可以人为规定,横纵坐标相加为 奇数 的格子连横纵坐标相加为 偶数 的格子. 如果一个格子横纵坐标相加为奇数,那么它的上下左右四个格子横纵坐标相加必定为偶数. ——代码 1 #include <cstdio> 2 #include <cstring> 3 4 using

二分图最大匹配,最小路径覆盖,最小点覆盖,最大独立集,最小边覆盖与建图方法

转载请注明出处(别管写的好坏,码字也不容易):http://blog.csdn.net/hitwhacmer1 前言:         有自己写的,有摘的别人的,前面是摘的,也是无心整理,出错是难免的,反正我都不会证明,智人见智,别被我误导了. §1图论点.边集和二分图的相关概念和性质 点覆盖.最小点覆盖 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是"点" 覆盖了所有"边"..极小点覆盖(minimal vertex covering):本身为点覆

POJ-2446-Chessboard(二分图匹配)

链接:https://vjudge.net/problem/POJ-2446#author=0 题意: 有一天,罗老板画了一块尺寸为M * N的棋盘.他希望许老师能够使用1 * 2的牌来覆盖棋盘.然而,他认为这很容易,所以他增大了难度,他在棋盘上打了一些洞 许老师必须遵守以下规则: 1.任何不是洞网格都应该只被一张卡覆盖. 2. 一张卡应该正好覆盖2个相邻非洞网格. 3. 洞不可以被卡片覆盖 你的任务是帮助许老师确定 根据上述规则 是否存在一种方案可以覆盖棋盘 思路: 二分图匹配.因为一个1*2

bzoj4025 二分图

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4025 [题解] 考虑对时间分治,用可撤回的启发式合并并查集来维护连通性. 二分图的条件是没有奇环,用并查集判即可. 对于时间区间[l,r],如果边在这期间都存在,那么就加入并查集,对于剩下的边分类,并且分治下去做. 对于每条边,在log个区间表示出来了,需要进行判断,启发式合并的getf是log的,所以复杂度为O(nlog^2n) # include <stdio.h> # includ

POJ2584 T-Shirt Gumbo 二分图匹配(网络流)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int inf=0x3f3f3f3f; 6 const int sink=30; 7 8 struct Edge 9 { 10 int to; 11 int next; 12 int capacity; 13 14 void assign(int t,int n,int c) 15 { 16 to=t; next=n; ca

棋盘游戏(二分图匹配)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 棋盘游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3200    Accepted Submission(s): 1897 Problem Description 小 希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放