这题也是一道经典的最小点覆盖问题,但是注意本题中不是整行整列地消除,而是消除连续的格子,因此先把连续的格子当成一个整体标号,然后当行列相交时连边。
var
r,c,nx,ny:longint;
s:array[1..50]of string;
g,tx,ty:array[1..3000,1..3000]of longint;
match,t:array[1..3000]of longint;
h:array[1..3000]of boolean;
procedure init;
var i,j:longint;
begin
nx:=0;ny:=0;
readln(r,c);
for i:=1 to r do readln(s[i]);
for i:=1 to r do
begin
j:=1;
while(j<=c)do
begin
if(s[i,j]='*')then
begin
inc(nx);
while(j<=c)and(s[i,j]='*')do
begin
tx[i,j]:=nx;inc(j);
end;
dec(j)
end;
inc(j);
end;
end;
for j:=1 to c do
begin
i:=1;
while(i<=r)do
begin
if(s[i,j]='*')then
begin
inc(ny);
while(i<=r)and(s[i,j]='*')do
begin
ty[i,j]:=ny;inc(i);
end;
dec(i);
end;
inc(i);
end;
end;
for i:=1 to r do
for j:=1 to c do
begin
if(s[i,j]='*')then
begin
inc(t[tx[i][j]]);
g[tx[i][j],t[tx[i][j]]]:=ty[i][j];
end;
end;
end;
function check(k:longint):boolean;
var i:longint;
begin
for i:=1 to t[k] do
if(not h[g[k,i]])then
begin
h[g[k,i]]:=true;
if(match[g[k,i]]=0)or(check(match[g[k,i]]))then
begin
match[g[k,i]]:=k;
exit(true);
end;
end;
exit(false);
end;
procedure hungarian;
var i,ans:longint;
begin
ans:=0;
for i:=1 to nx do
begin
fillchar(h,sizeof(h),0);
if(check(i))then inc(ans);
end;
writeln(ans);
end;
begin
init;
hungarian;
end.