• POJ 2446 Chessboard (二分匹配)


    Chessboard
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 10743   Accepted: 3338

    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 to cover the board. However, she thinks it too easy to bob, so she makes some holes on the board (as shown in the figure below).
    We call a grid, which doesn’t contain a hole, a normal grid. Bob has to follow the rules below: 1. Any normal grid should be covered with exactly one card. 2. One card should cover exactly 2 normal adjacent grids.
    Some examples are given in the figures below:
    A VALID solution.
    An invalid solution, because the hole of red color is covered with a card.
    An invalid solution, because there exists a grid, which is not covered.
    Your task is to help Bob to decide whether or not the chessboard can be covered according to the rules above.

    Input

    There are 3 integers in the first line: m, n, k (0 < m, n <= 32, 0 <= K < m * n), the number of rows, column and holes. In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column.

    Output

    If the board can be covered, output "YES". Otherwise, output "NO".

    Sample Input

    4 3 2
    2 1
    3 3
    

    Sample Output

    YES

    Hint

    A possible solution for the sample input.

    Source

    POJ Monthly,charlescpp
     
     
     
    简单的而二分图的模板题。
    建图方法好像不唯一。
    我是把每个空格子当成一个点。
    然后对于每个格子如果可以往上、下、左、右去找可以建立的边。
    然后求最大匹配,如果最大匹配数刚好等于空格子数,输出YES,否则NO。
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    
    /* **************************************************************************
    //二分图匹配(匈牙利算法的DFS实现)
    //初始化:g[][]两边顶点的划分情况
    //建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配
    //g没有边相连则初始化为0
    //uN是匹配左边的顶点数,vN是匹配右边的顶点数
    //调用:res=hungary();输出最大匹配数
    //优点:适用于稠密图,DFS找增广路,实现简洁易于理解
    //时间复杂度:O(VE)
    //***************************************************************************/
    //顶点编号从0开始的
    const int MAXN=1610;
    int uN,vN;//u,v数目
    int g[MAXN][MAXN];
    int linker[MAXN];
    bool used[MAXN];
    bool dfs(int u)//从左边开始找增广路径
    {
        int v;
        for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
          if(g[u][v]&&!used[v])
          {
              used[v]=true;
              if(linker[v]==-1||dfs(linker[v]))
              {//找增广路,反向
                  linker[v]=u;
                  return true;
              }
          }
        return false;//这个不要忘了,经常忘记这句
    }
    int hungary()
    {
        int res=0;
        int u;
        memset(linker,-1,sizeof(linker));
        for(u=0;u<uN;u++)
        {
            memset(used,0,sizeof(used));
            if(dfs(u)) res++;
        }
        return res;
    }
    
    bool graph[50][50];
    int num[50][50];
    
    int main()
    {
        int n,m,k;
        int x,y;
        while(scanf("%d%d%d",&n,&m,&k)==3)
        {
            memset(g,0,sizeof(g));
            memset(graph,false,sizeof(graph));
            while(k--)
            {
                scanf("%d%d",&x,&y);
                x--;
                y--;
                graph[y][x]=true;
            }
            int tol=0;
            for(int i=0;i<n;i++)
              for(int j=0;j<m;j++)
              {
                  if(graph[i][j]==false)
                    num[i][j]=tol++;
              }
            uN=vN=tol;
            for(int i=0;i<n;i++)
               for(int j=0;j<m;j++)
                  if(!graph[i][j])
                  {
                      int u=num[i][j];
                      if(i>0 && !graph[i-1][j])g[u][num[i-1][j]]=1;
                      if(j>0 && !graph[i][j-1])g[u][num[i][j-1]]=1;
                      if(i<n-1 && !graph[i+1][j])g[u][num[i+1][j]]=1;
                      if(j<m-1 && !graph[i][j+1])g[u][num[i][j+1]]=1;
                  }
            if(hungary()==tol)printf("YES\n");
            else printf("NO\n");
    
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    sql 删除表数据并使ID自增重置
    PHP的常用字符串处理
    一个http请求的详细过程
    elasticsearch7.7-postman-json脚本
    elasticsearch7.7入门三-小试牛刀-批量导入json数据
    elasticsearch7.7入门三-小试牛刀
    elasticsearch7.7入门二-安装
    elasticsearch7.7入门一-介绍
    java8新特性七-Date Time API
    java8新特性五-Stream
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2789630.html
Copyright © 2020-2023  润新知