分析
我们知道对于没有障碍的情况就是将横轴点于纵轴点连边
于是对于这种有障碍的情况我们还是分横轴纵轴考虑
只不过对于有障碍的一整条分为若干个无障碍小段来处理
然后将标号小段连边,跑最大匹配即可
代码
#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; }
原文地址:https://www.cnblogs.com/yzxverygood/p/10336017.html
时间: 2024-10-05 23:07:50