bzoj1735 [Usaco2005 jan]Muddy Fields 泥泞的牧场
分析
我们知道对于没有障碍的情况就是将横轴点于纵轴点连边
于是对于这种有障碍的情况我们还是分横轴纵轴考虑
只不过对于有障碍的一整条分为若干个无障碍小段来处理
然后将标号小段连边,跑最大匹配即可
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int n,m,be1[110][110],be2[110][110],g[3000][3000],Ans,T,used[3000],belong[3000];
char s[110][110];
inline bool work(int x){
for(int i=1;i<=m;i++)
if(used[i]!=T&&g[x][i]){
used[i]=T;
if(!belong[i]||work(belong[i])){
belong[i]=x;
return 1;
}
}
return 0;
}
inline void go(){
for(int i=1;i<=n;i++){
T=i;
if(work(i))Ans++;
}
}
int main(){
int w,r,i,j,k;
scanf("%d%d",&w,&r);
for(i=0;i<w;i++)
scanf("%s",s[i]);
for(i=0;i<w;i++){
k=1;
for(j=0;j<r;j++){
if(s[i][j]=='.'&&!k)k=1;
if(s[i][j]=='*'){
if(k)n++,k=0;
be1[i][j]=n;
}
}
}
for(i=0;i<r;i++){
k=1;
for(j=0;j<w;j++){
if(s[j][i]=='.'&&!k)k=1;
if(s[j][i]=='*'){
if(k)m++,k=0;
be2[j][i]=m;
}
}
}
for(i=0;i<w;i++)
for(j=0;j<r;j++)
g[be1[i][j]][be2[i][j]]=1;
go();
cout<<Ans;
return 0;
}