/* zoj_1654 最大流(最大二分匹配) 这题大家可以看黄源河大牛的论文,很牛B的建图思路。 匈牙利算法易解之。 */ #include <iostream> #include <cstdio> #include <vector> #include <string.h> #define N 2550 using namespace std; char map[55][55]; bool gra[N][N],state[N]; int result[N]; int n,m; struct block { int id,stax,stay,endx,endy; block( int a,int b,int c,int d,int e ): id(a),stax(b),stay(c),endx(d),endy(e) {} }; vector <block>ver,hor; void build() { int i,j,k,id; id=1; for( i=0;i<m;i++ ) { for( j=0;j<n; ) if( map[i][j]=='o' ) { for( k=j+1;k<n;k++ ) { if( map[i][k]=='#' ) break; } hor.push_back( block( id++,i,j,i,k-1 ) ); j=k+1; } else j++; } id=1; for( i=0;i<n;i++ ) { for( j=0;j<m; ) if( map[j][i]=='o' ) { for( k=j+1;k<m;k++ ) { if( map[k][i]=='#' ) break; } ver.push_back( block( id++,j,i,k-1,i ) ); j=k+1; } else j++; } } void graph() { int i,j; memset( result,0,sizeof(result) ); memset( gra,0,sizeof(gra) ); for( i=0;i<hor.size();i++ ) { for( j=0;j<ver.size();j++ ) if( ver[j].stay>=hor[i].stay && ver[j].stay<=hor[i].endy && hor[i].stax>=ver[j].stax && hor[i].stax<=ver[j].endx && map[ hor[i].stax ][ ver[j].stay ]=='o' ) gra[ hor[i].id ][ ver[j].id ]=true; } } bool find( int a ) { int i; for( i=1;i<=ver.size();i++ ) { if( gra[a][i] && !state[i] ) { state[i]=1; if( !result[i] || find( result[i] ) ) { result[i]=a; return true; } } } return false; } int main() { int T,i,j,ans,co; scanf( "%d",&T ); co=1; while( T-- ) { scanf( "%d%d",&m,&n ); getchar(); for( i=0;i<m;i++ ) { for( j=0;j<n;j++ ) scanf( "%c",&map[i][j] ); getchar(); } build(); graph(); ans=0; for( i=1;i<=hor.size();i++ ) { memset( state,0,sizeof(state) ); if( find(i) ) ans++; } printf( "Case :%d\n%d\n",co,ans ); co++; hor.clear(); ver.clear(); } return 0; }