zoukankan      html  css  js  c++  java
  • poj 2446二分图匹配

    题意:爱丽丝和波波经常玩棋盘游戏,爱丽丽画出一个m*n的棋盘,让波波在棋盘中填充1*2大小的矩形条,而且爱丽丝不想这么轻易让波波赢,她将m*n的棋盘中挖掉k个方格。

    1.每个矩形条必需覆盖矩阵中相临两个方格
    2.矩形条不能覆盖挖去的方格。
    对于给定的m*n的且某些方格被挖去的矩阵,问用某种覆盖方法能否将除挖掉的方格外所有方格全部覆盖,若能,输出YES,否则输出NO。

    思路:
    矩形条每次覆盖相临两个方格。那么对两个任意方格(看作结点),如果它们分属两个不同的集合的话,那么它们之间存在边的情况只有它们是相临的方格的时候。这样一来,我们可以将矩阵中所有元素分成两个点集,相临点间存在边的关系。那么如何分这两个集合呢, 发现一个方块的行标和列标之和若为奇数则它周围的四个方块的行标和列标之和必为偶数;一个方块的行标和列标之和若为偶数则它周围的四个方块的行标和列标之和必为奇数,奇数一个集合,偶数一个集合,只连左边和上边。这样一个二分图就建完了。

      1 // File Name: 2446.cpp
      2 // Author: Missa
      3 // Created Time: 2013/4/3 星期三 13:56:33
      4 
      5 #include<iostream>
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<algorithm>
      9 #include<cmath>
     10 #include<queue>
     11 #include<stack>
     12 #include<string>
     13 #include<vector>
     14 #include<cstdlib>
     15 #include<map>
     16 #include<set>
     17 using namespace std;
     18 #define CL(x,v) memset(x,v,sizeof(x));
     19 #define R(i,st,en) for(int i=st;i<en;++i)
     20 #define LL long long
     21 #define inf 0x3f3f3f3f
     22 
     23 const int maxn = 33;
     24 int n,m,k;
     25 int in[maxn][maxn];
     26 int g[maxn * maxn][maxn * maxn];
     27 int nx,ny;
     28 bool vis[maxn * maxn];
     29 int link[maxn * maxn];
     30 bool dfs(int x)
     31 {
     32     R(y, 1, ny+1)
     33     {
     34         if(!vis[y] && g[x][y])
     35         {
     36             vis[y] =1;
     37             if(link[y] == -1 || dfs(link[y]))
     38             {
     39                 link[y] = x;
     40                 return 1;
     41             }
     42         }
     43     }
     44     return false;
     45 }
     46 int maxmatch()
     47 {
     48     int ans = 0;
     49     CL(link,-1);
     50     R(x, 1, nx+1)
     51     {
     52         CL(vis, 0);
     53         if(dfs(x)) ans++;
     54     }
     55     return ans;
     56 }
     57 void init()
     58 {
     59     nx = ny = 0;
     60     CL(g, 0);
     61     for (int i = 1; i <= n; ++i)
     62     {
     63         for (int j = 1; j <= m; ++j)
     64         {
     65             if (in[i][j] == -1) continue;
     66             if ((i + j) & 1)
     67             {
     68                 in[i][j] = ++nx;
     69                 if (i - 1 >= 1 && in[i-1][j] != -1)
     70                     g[nx][in[i-1][j]] = 1;
     71                 if (j - 1 >= 1 && in[i][j-1] != -1)
     72                     g[nx][in[i][j-1]] = 1;
     73             }
     74             else
     75             {
     76                 in[i][j] = ++ny;
     77                 if (i - 1 >= 1 && in[i-1][j] != -1)
     78                     g[in[i-1][j]][ny] = 1;
     79                 if (j - 1 >= 1 && in[i][j-1] != -1)
     80                     g[in[i][j-1]][ny] = 1;
     81             }
     82         }
     83     }
     84 }
     85 int main()
     86 {
     87     while(~scanf("%d%d%d",&n, &m, &k))
     88     {
     89         CL(in, 0);
     90         R(i, 0, k)
     91         {
     92             int x, y;
     93             scanf("%d%d", &y, &x);
     94             in[x][y] = -1;
     95         }
     96         if((n * m - k) & 1)
     97         {
     98             printf("NO\n");
     99             continue;
    100         }
    101         init();
    102         if(maxmatch() * 2 == (n * m - k))
    103             printf("YES\n");
    104         else
    105             printf("NO\n");
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    Ajax学习笔记3种Ajax的实现
    分页学习笔记真分页和假分页实现
    学习笔记链表练习,模仿StringBuilder的山寨版StringBuilder
    学习笔记将Asp.Net网站发布到IIS的四种方法及注意事项
    3D 音频技术产品介绍(1):Iosono the future of spatial audio
    国际顶级语音信号增强工作组:IWAENC(International Workshop on Acoustic Echo and Noise Control)
    转:《欢聚时代(多玩YY)IPO招股书》(概要)
    苏州阔地网络科技有限公司专利分析
    CELT和SILK以及Opus的位分配方法
    ISAC 码流格式
  • 原文地址:https://www.cnblogs.com/Missa/p/2997960.html
Copyright © 2011-2022 走看看