/*
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;
}
zoj 1654 Place the Robots
最新推荐文章于 2024-09-13 18:58:52 发布