zoukankan      html  css  js  c++  java
  • P1035

    P1035

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 87  解决: 36
    [提交][状态][讨论版]

    题目描述

    给出一张n*n(n< =100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖。

    输入

    第一行为n,m(表示有m个删除的格子) 第二行到m+1行为x,y,分别表示删除格子所在的位置 x为第x行 y为第y列 

    输出

    一个数,即最大覆盖格数

    样例输入

    8 0

    样例输出

    32

    提示

    经典问题

     建图,比较简单,一般人都想得到,所以一个点与其上下左右的点连边,然后就可以了,求一次二分图最大匹配。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7  
     8 const int x[4]={0,0,1,-1},y[4]={-1,1,0,0};
     9  
    10 int n,m;
    11 bool map[207][207],flag[70007];
    12 int head[17010],cnt,next[70007],rea[70007];
    13 int fa[17010];
    14 void add(int u,int v)
    15 {
    16     cnt++;
    17     next[cnt]=head[u];
    18     head[u]=cnt;
    19     rea[cnt]=v;
    20 }
    21 bool dfs(int u)
    22 {
    23     for(int i=head[u];i!=-1;i=next[i])
    24     {
    25         int v=rea[i];
    26         if(flag[v]==false)
    27         {
    28             flag[v]=1;
    29             if(fa[v]==-1||dfs(fa[v]))
    30             {
    31                 fa[v]=u;
    32                 return true;
    33             }
    34         }
    35     }
    36     return false;
    37 } 
    38 int solve()
    39 {
    40     int num=0;
    41     memset(fa,-1,sizeof(fa));
    42     for(int i=1;i<=n*n;i++)
    43     {
    44         memset(flag,false,sizeof(flag));
    45         num+=dfs(i);
    46     }
    47     return num;
    48 }
    49 int main()
    50 {
    51     cnt=0;
    52     memset(head,-1,sizeof(head));
    53     memset(map,false,sizeof(map));
    54     scanf("%d%d",&n,&m);
    55     for(int i=1;i<=m;i++)
    56     {
    57         int x,y;
    58         scanf("%d%d",&x,&y);
    59         map[x][y]=true;
    60     }
    61     for(int i=1;i<=n;i++)
    62       for(int j=1;j<=n;j++)
    63           if(!map[i][j])
    64           {
    65               int numx=(i-1)*n+j;
    66               for(int k=0;k<4;k++)
    67               {
    68                   int xx=i+x[k],yy=j+y[k];
    69                   if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&!map[xx][yy])
    70                    {
    71                       int numy=(xx-1)*n+yy;
    72                       add(numx,numy);
    73                    }
    74               }
    75            }
    76     printf("%d
    ",solve()/2);
    77 }
  • 相关阅读:
    好系统重装助手重装电脑系统步骤
    U盘加载速度慢的解决方法
    Win10应用商店缓存信息多如何去清理?
    怎么消除文件左上角的白色小框?
    U盘被识别但不显示盘符怎么样才能解决?
    【Gamma】Scrum Meeting 2
    【技术博客】 关于laravel5.1中文件上传测试的若干尝试
    【Beta】Phylab 发布说明
    【Beta】Phylab 测试报告
    【Beta】Scrum Meeting 10
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7210636.html
Copyright © 2011-2022 走看看