zoukankan      html  css  js  c++  java
  • hdu--5093--经典二分图的行列匹配

    感觉图论的题 都是难在 如何建图上 本题也是如此

    我们主要是将行与列 分开来考虑  每一座冰山隔开的海水 都可以看成一个“块” 在这上面是可以放船的 然后是将这连续的海水可能中间会有冰 但不影响看成一个块

    列 也是同样处理的     然后 每一个 列与行的交点的海水 不就是说明这个行与列是矛盾的 只能存在一个 就将它们连边.  最后就是去求 二分图的 最大匹配

      1 #include <iostream>
      2 #include <cstring>
      3 using namespace std;
      4 
      5 int cntX , cntY , n , m;
      6 const int size = 55;
      7 char mp[size][size];
      8 int x[size][size];
      9 int y[size][size];
     10 bool vis[size*size];
     11 int linker[size*size];
     12 bool edge[size*size][size*size];
     13 
     14 void init( )
     15 {
     16     cntX = cntY = 1;
     17     memset( x , 0 , sizeof(x) );
     18     memset( y , 0 , sizeof(y) );
     19     memset( edge , false , sizeof(edge) );
     20     memset( linker , 0 , sizeof(linker) );
     21 }
     22 
     23 void solveX( )
     24 {
     25     for( int i = 1 ; i<=n ; i++ )
     26     {
     27         int j = 1;
     28         while( j<=m )
     29         {
     30             if( mp[i][j]=='*' )
     31             {
     32                 x[i][j] = cntX;
     33                 ++ j;
     34                 while( j<=m )
     35                 {
     36                     if( mp[i][j]=='*' )
     37                     {
     38                         x[i][j] = cntX;
     39                         ++ j;
     40                     }
     41                     else if( mp[i][j]=='o' )
     42                     {
     43                         ++ j;
     44                         continue;
     45                     }
     46                     else
     47                     {
     48                         break;
     49                     }
     50                 }
     51                 ++ cntX;
     52             }
     53             else
     54             {
     55                 ++ j;
     56             }
     57         }
     58     }
     59 }
     60 
     61 void solveY( )
     62 {
     63     for( int i = 1 ; i<=m ; i++ )//
     64     {
     65         int j = 1;
     66         while( j<=n )//
     67         {
     68             if( mp[j][i]=='*' )
     69             {
     70                 y[j][i] = cntY;
     71                 edge[ x[j][i] ][ y[j][i] ] = true;
     72                 ++ j;
     73                 while( j<=n )
     74                 {
     75                     if( mp[j][i]=='*' )
     76                     {
     77                         y[j][i] = cntY;
     78                         edge[ x[j][i] ][ y[j][i] ] = true;
     79                         ++ j;
     80                     }
     81                     else if( mp[j][i]=='o' )
     82                     {
     83                         ++ j;
     84                         continue;
     85                     }
     86                     else
     87                     {
     88                         break;
     89                     }
     90                 }
     91                 ++ cntY;
     92             }
     93             else
     94             {
     95                 ++ j;
     96             }
     97         }
     98     }
     99 }
    100 
    101 bool dfs( int u )
    102 {
    103     for( int v = 1 ; v<cntY ; v++ )
    104     {
    105         if( edge[u][v] && !vis[v] )
    106         {
    107             vis[v] = true;
    108             if( !linker[v] || dfs( linker[v] ) )
    109             {
    110                 linker[v] = u;
    111                 return true;
    112             }
    113         }
    114     }
    115     return false;
    116 }
    117 
    118 int solve( )
    119 {
    120     int ans = 0;
    121     for( int i = 1 ; i<cntX ; i++ )
    122     {
    123         memset( vis , false , sizeof(vis) );
    124         if( dfs(i) )
    125             ++ ans;
    126     }    
    127     return ans;
    128 }
    129 
    130 int main()
    131 {
    132     cin.sync_with_stdio(false);
    133     int t , ans;
    134     while( cin >> t )
    135     {
    136         while( t-- )
    137         {
    138             init( );
    139             cin >> n >> m;
    140             for( int i = 1 ; i<=n ; i++ )
    141             {
    142                 cin >> (mp[i]+1);
    143             }
    144             solveX( );
    145             solveY( );
    146             /*
    147             for( int i = 1 ; i<=n ; i++ )
    148             {
    149                 for( int j = 1 ; j<=m ; j++ )
    150                 {
    151                     cout << x[i][j] << " ";
    152                 }
    153                 cout << endl;
    154             }
    155             for( int i = 1 ; i<=m ; i++ )
    156             {
    157                 for( int j = 1 ; j<=n ; j++ )
    158                 {
    159                     cout << y[i][j] << " ";
    160                 }
    161                 cout << endl;
    162             }
    163             */
    164             ans = solve( );
    165             cout << ans << endl;
    166         }
    167     }
    168     return 0;
    169 }
    View Code
  • 相关阅读:
    老贴纪念九(蓝色 白色 绿色(前四天))
    进入6月
    老贴纪念七!(敏感:二十年了,而青春从来没有离开过)
    一个关于inet_ntoa的奇怪问题
    一个通用的Makefile模板
    【记录】find+tar命令组合
    Linux SDIO WIFI驱动的编译
    编译静态库和动态库的Makefile文件
    分解成连续数字的和
    linux nc命令示例
  • 原文地址:https://www.cnblogs.com/radical/p/4101341.html
Copyright © 2011-2022 走看看