zoukankan      html  css  js  c++  java
  • POJ 2226 Muddy Fields 二分图(难点在于建图)

    题意:给定一个矩阵和它的N行M列,其中有一些地方有水,现在有一些长度任意,宽为1的木板,要求在板不跨越草,用一些木板盖住这些有水的地方,问至少需要几块板子?

    思路:首先想到如果没有不准跨越草的条件则跟POJ 3041题意一样(如果想看的话可以点击这里),然而这一题多了个条件,那么将矩阵转化的方式需要改变,不能直接将行列分成两个集合了。需要先查看两遍矩阵,一遍横向查看有无连续‘*’的情况,若连续说明一块板子就可以覆盖,所以标记为同样的数字,反之则不同;同理另一遍纵向查看矩阵连续'*'的情况,处理方式同上。这样就建图完毕了。

      1 #include<cstdio>
      2 
      3 #include<cstring>
      4 
      5 #include<iostream>
      6 
      7 #include<algorithm>
      8 
      9 using namespace std;
     10 
     11  
     12 
     13 const int N = 600;
     14 
     15 int n, m, p, q;
     16 
     17 bool lin[N][N];
     18 
     19 int used[N], arr[N], mark[N][N];
     20 
     21 char map[N][N];
     22 
     23  
     24 
     25 bool find(int x)
     26 
     27 {
     28 
     29     for(int j = 1; j <= q; j++)
     30 
     31     {
     32 
     33         if(lin[x][j] && used[j] == 0)
     34 
     35         {
     36 
     37             used[j] = 1;
     38 
     39             if(arr[j] == 0 || find(arr[j]))
     40 
     41             {
     42 
     43                 arr[j] = x;
     44 
     45                 return true;
     46 
     47             }
     48 
     49         }
     50 
     51     }
     52 
     53     return false;
     54 
     55 }
     56 
     57 
     58 
     59 int main()
     60 
     61 {
     62 
     63     int r, c;
     64 
     65     while(~scanf("%d%d", &n, &m))
     66 
     67     {
     68 
     69         memset(map, '0', sizeof(map));
     70 
     71         for(int i = 0; i < n; i++)
     72 
     73         {
     74 
     75             scanf("%s", &map[i]);
     76 
     77         }
     78 
     79         memset(lin, false , sizeof(lin));
     80 
     81         memset(arr, 0, sizeof(arr));
     82 
     83         p = 0;
     84 
     85         for(int i = 0; i < n; i++)
     86 
     87         {
     88 
     89             for(int j = 0; j < m; j++)
     90 
     91             {
     92 
     93                 if(map[i][j] == '*')
     94 
     95                 {
     96 
     97                     if(map[i][j-1] != '*')//横向查看
     98 
     99                     {
    100 
    101                         p++;
    102 
    103                     }
    104 
    105                     mark[i][j] = p;
    106 
    107                 }    
    108 
    109             }
    110 
    111         }
    112 
    113         q = 0;
    114 
    115         for(int j = 0; j < m; j++)
    116 
    117         {
    118 
    119             for(int i = 0; i < n; i++)
    120 
    121             {
    122 
    123                 if(map[i][j] == '*')
    124 
    125                 {
    126 
    127                     if(map[i-1][j] != '*')//纵向查看
    128 
    129                     {
    130 
    131                         q++;
    132 
    133                     }
    134 
    135                     lin[mark[i][j]][q] = true;//横向已经检查完了可以直接建图了
    136 
    137                 }
    138 
    139             }
    140 
    141         }
    142 
    143         int all = 0;
    144 
    145         for(int i = 1; i <= p; i++)
    146 
    147         {
    148 
    149             memset(used, 0, sizeof(used));
    150 
    151             if(find(i))
    152 
    153                 ++all;
    154 
    155         }
    156 
    157         printf("%d
    ", all);
    158 
    159     }
    160 
    161     return 0;
    162 
    163 }
    View Code
  • 相关阅读:
    wpf 3D学习
    vs2010莫名崩溃初探
    Wcf(,service callback client)
    MEF和CompositionContainer学习
    认知Media Queries让浏览器人性化
    移动互联网产品设计的7大误区
    RUP中的迭代模型
    前端工程师的价值体现在哪里?
    做用户研究时,如何挑选合适的用户?
    晒晒 邀请函!感恩节 感谢组织!让我挡上末班车!哈哈!
  • 原文地址:https://www.cnblogs.com/llllrj/p/9398327.html
Copyright © 2011-2022 走看看