zoukankan      html  css  js  c++  java
  • POJ 2446 最小点覆盖

    Chessboard
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 14787   Accepted: 4607

    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
     
     
    题目意思:
    一个n*m的棋盘,现用1*2的木板覆盖棋盘,其中有黑色圆的棋盘单位不能被覆盖。问能否把棋盘中可以覆盖的单位全部覆盖(不能重复覆盖)。
     
    思路:
    相邻棋盘单位奇偶性不同建图,判断最大匹配*2是否等于可以覆盖点数即可。
     
     
    代码:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <vector>
     6 #include <queue>
     7 #include <cmath>
     8 #include <set>
     9 using namespace std;
    10 
    11 #define N 35
    12 
    13 int max(int x,int y){return x>y?x:y;}
    14 int min(int x,int y){return x<y?x:y;}
    15 int abs(int x,int y){return x<0?-x:x;}
    16 
    17 int n, m;
    18 vector<int>ve[N*N];
    19 int from[N*N];
    20 bool visited[N*N];
    21 
    22 
    23 int march(int u){
    24     int i, v;
    25     for(i=0;i<ve[u].size();i++){
    26         v=ve[u][i];
    27         if(!visited[v]){
    28             visited[v]=true;
    29             if(from[v]==-1||march(from[v])){
    30                 from[v]=u;
    31                 return 1;
    32             }
    33         }
    34     }
    35     return 0;
    36 }
    37 int map[N][N];
    38 main()
    39 {
    40     int i, j, k;
    41     
    42     int x, y;
    43     while(scanf("%d %d %d",&n,&m,&k)==3){
    44         memset(map,-1,sizeof(map));
    45         int maxh=0;
    46         for(i=0;i<n;i++){
    47             for(j=0;j<m;j++){
    48                 if(j==0){
    49                     if(i==0) map[i][j]=0;
    50                     else {
    51                         if(m&1) map[i][j]=map[i-1][m-1]+1;
    52                         else map[i][j]=map[i-1][m-1]+2;
    53                     }
    54                 }
    55                 else map[i][j]=map[i][j-1]+1;
    56                 maxh=max(maxh,map[i][j]);
    57             //    printf("%d ",map[i][j]);
    58             }
    59             //cout<<endl;
    60         }
    61         for(i=0;i<k;i++){
    62             scanf("%d %d",&x,&y);
    63             map[y-1][x-1]=-1;
    64         } 
    65         int nn=0;
    66         for(i=0;i<n;i++){
    67             for(j=0;j<m;j++){
    68                 if(map[i][j]==-1) nn++;
    69             }
    70         }
    71         
    72         for(i=0;i<=maxh;i++) ve[i].clear();
    73         for(i=0;i<n;i++){
    74             for(j=0;j<m;j++){
    75                 if(map[i][j]!=-1&&(map[i][j]&1)){
    76                     if(i>0&&map[i-1][j]!=-1) ve[map[i][j]].push_back(map[i-1][j]);
    77                     if(i<n-1&&map[i+1][j]!=-1) ve[map[i][j]].push_back(map[i+1][j]);
    78                     if(j>0&&map[i][j-1]!=-1) ve[map[i][j]].push_back(map[i][j-1]);
    79                     if(j<m-1&&map[i][j+1]!=-1) ve[map[i][j]].push_back(map[i][j+1]);
    80                 }
    81             }
    82         }
    83         int num=0;
    84         memset(from,-1,sizeof(from));
    85         for(i=0;i<=maxh;i++){
    86             memset(visited,false,sizeof(visited));
    87             if((i&1)&&march(i)) num++;
    88         }
    89         if(num*2==n*m-nn) printf("YES
    ");
    90         else printf("NO
    "); 
    91     }
    92 }
  • 相关阅读:
    纪中培训 8月8日 day3 考试
    【置顶】博客搬迁
    图论②——??? (poj 3662)
    图论①——??? (2750: [HAOI2012]Road)
    树形dp①
    区间dp②
    区间dp①
    线性dp②
    字符串算法①——kmp
    图论——最小生成树①
  • 原文地址:https://www.cnblogs.com/qq1012662902/p/4643946.html
Copyright © 2011-2022 走看看