思维构建二分图的思路参考了这篇博客:参考
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxv=1010;
int LN,RN,l,r;
bool visit[maxv];
char mmap[maxv][maxv];
int link[maxv];
int Lmap[maxv][maxv],Rmap[maxv][maxv],map_link[maxv][maxv];
void init() {
l=0,r=0;
memset(Lmap,0,sizeof Lmap);
memset(Rmap,0,sizeof Rmap);
memset(map_link,0,sizeof map_link);
memset(link,-1,sizeof link);
}
bool dfs(int x){
for(int y=1;y<=RN;y++){
if(map_link[x][y]&&visit[y]==false){
visit[y]=true;
if(link[y]==-1||dfs(link[y])){
link[y]=x;
return true;
}
}
}
return false;
}
int hungary(){//匈牙利算法
int res=0;
for(int x=1;x<=LN;x++){
memset(visit,false,sizeof visit);
if(dfs(x))
res++;
}
cout<<res<<endl;
}
int main(void) {
#ifndef ONLINE_JUDGE
freopen("E:\\input.txt","r",stdin);
#endif // ONLINE_JUDGE
int R,C;
while(cin>>R>>C) {
init();
for(int i=1; i<=R; i++)
for(int j=1; j<=C; j++)
cin>>mmap[i][j];
for(int i=1; i<=R; i++)//构建L序列
for(int j=1; j<=C; j++)
if(mmap[i][j]=='*') {
l++;
while(j<=C&&mmap[i][j]=='*')
Lmap[i][j]=l,j++;
}
for(int j=1; j<=C; j++)//构建R序列
for(int i=1; i<=R; i++)
if(mmap[i][j]=='*') {
r++;
while(i<=R&&mmap[i][j]=='*')
Rmap[i][j]=r,i++;
}
for(int i=1;i<=R;i++)//构建L链接R的路径
for(int j=1;j<=C;j++)
if(mmap[i][j]=='*')
map_link[Lmap[i][j]][Rmap[i][j]]=1;
LN=l,RN=r;
hungary();
}
return 0;
}