将行中连续的' . '当作X集的一个点,列中连续的’ . ‘看成Y集中的一个点,然后把每一个’ . ‘看成一条边,连接Xi,Yj。
则问题转化成求此二分的最大匹配数。每找到一条匹配边的意义是找到了一个点放置一个,并且覆盖了所在的连续的行和列。
所以答案即为此二分图的最大匹配。
20s的时限,只跑了29ms。。。。这是有多不相信自己的服务器。。。。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long LL
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 1000000007
#define LM(a,b) (((ULL)(a))<<(b))
#define RM(a,b) (((ULL)(a))>>(b))
using namespace std;
const LL MAXN = 100001;
struct N
{
int v,next;
}edge[MAXN*2];
int head[MAXN];
int Top;
void Link(int u,int v)
{
edge[Top].v = v;
edge[Top].next = head[u];
head[u] = Top++;
}
void Init_head_Top(int n)
{
memset(head,-1,sizeof(int)*(n+2));
Top = 0;
}
int Match_Point[MAXN];
bool mark[MAXN];
bool dfs(int s)
{
for(int p = head[s] ; p != -1; p = edge[p].next)
{
if(mark[edge[p].v] == false)
{
mark[edge[p].v] = true;
if(Match_Point[edge[p].v] == -1 || dfs(Match_Point[edge[p].v]))
{
Match_Point[s] = edge[p].v;
Match_Point[edge[p].v] = s;
return true;
}
}
}
return false;
}
int Cal_Max_Match(int n)
{
int ans = 0;
for(int i = 1;i <= n; ++i)
{
if(Match_Point[i] == -1)
{
memset(mark,false,sizeof(bool)*(n+2));
if(dfs(i))
ans++;
}
}
return ans;
}
char Map[110][110];
int ansx[110][110];
int ansy[110][110];
int main()
{
int n;
int i,j;
while(scanf("%d",&n) != EOF)
{
for(i = 1;i <= n; ++i)
{
scanf("%s",Map[i]+1);
}
memset(ansx,-1,sizeof(ansx));
memset(ansy,-1,sizeof(ansy));
memset(Match_Point,-1,sizeof(int)*(n*n*2+2));
int ty = 0;
for(i = 1;i <= n; ++i)
{
for(j = 1;j <= n; ++j)
{
if(Map[i][j] == '.')
{
ansx[i][j] = (ansx[i][j-1] == -1 ? ++ty : ansx[i][j-1]);
}
}
}
Init_head_Top(n*n*2);
int ans = 0;
for(j = 1;j <= n; ++j)
{
for(i = 1;i <= n; ++i)
{
if(Map[i][j] == '.')
{
ansy[i][j] = (ansy[i-1][j] == -1 ? ++ty : ansy[i-1][j]);
Link(ansx[i][j],ansy[i][j]);
Link(ansy[i][j],ansx[i][j]);
if(Match_Point[ansx[i][j]] == -1 && Match_Point[ansy[i][j]] == -1)
{
Match_Point[ansx[i][j]] = ansy[i][j],Match_Point[ansy[i][j]] = ansx[i][j],ans++;
}
}
}
}
printf("%d\n",ans+Cal_Max_Match(ty));
}
return 0;
}