解法1:我们可以把每个空地看成一个点 , 然后把所有有关联的空地之间连一条边 , 再求所得到的图的最大独立集 , 但是最大独立集是一个NP问题 , 因此并没有有效的算法 , 来求出这个。
解法2:分别把每一行、每一列看成是一个状态 , 最后求最大匹配
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 2600
char ky[52][52];
int xs[52][52] , ys[52][52];
int pre[maxn] , cy[maxn];
vectorgrap[maxn];
int n , m;
void init()
{
for(int i = 1; i <= 2500 ; i++)
grap[i].clear();
memset(cy , -1 , sizeof(cy));
memset(xs , 0 ,
sizeof(xs));
memset(ys , 0 , sizeof(ys));
}
int path(int u)
{
for(int i = 0; i < grap[u].size() ; i++)
{
int v = grap[u][i];
if(!pre[v])
{
pre[v] = 1;
if(cy[v] == -1 || path(cy[v]))
{
cy[v] = u;
return 1;
}
}
}
return 0;
}
int maxmatch()
{
int res = 0;
memset(cy , -1 , sizeof(cy));
for(int i = 1; i <= n; i++)
{
memset(pre , 0 , sizeof(pre));
res += path(i);
}
return res;
}
int main()
{
int t;
cin>>t;
int gh = 1;
while(t--)
{
int x , y;
init();
printf("Case :%d\n" , gh++);
scanf("%d %d" , &x , &y);
int i , j , g , h;
for(i = 0; i < x; i++)
scanf("%s" , ky[i]);
n = 1 , m = 1;
h = 0;
for(i = 0; i < x; i++)
{
g = 0;
for(j = 0; j < y; j++)
{
if(ky[i][j] == 'o')
xs[i][j] = n , g = 1 , h = n;
if(ky[i][j] == '#' && g)
n += 1 , g = 0;
}
if(g)
n += 1 , g = 0;
}
n = h , h = 0;
for(i = 0; i < y; i++)
{
g = 0;
for(j = 0; j < x; j++)
{
if(ky[j][i] == 'o')
ys[j][i] = m , g = 1 , h = m;
if(ky[j][i] == '#' && g)
m += 1 , g = 0;
}
if(g)
m += 1 , g = 0;
}
for(i = 0; i < x; i++)
for(j = 0; j < y; j++)
if(ky[i][j] == 'o')
{
grap[xs[i][j]].push_back(ys[i][j]);
}
//printf("Case :%d\n" , gh++);
cout<<maxmatch()<<endl;
}
return 0;
}
解法2:分别把每一行、每一列看成是一个状态 , 最后求最大匹配
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 2600
char ky[52][52];
int xs[52][52] , ys[52][52];
int pre[maxn] , cy[maxn];
vectorgrap[maxn];
int n , m;
void init()
{
}
int path(int u)
{
}
int maxmatch()
{
}
int main()
{
}