匈牙利。
这题感觉上跟之前羊老师出的题挺像?只不过前面那题是完美匹配?
把它分成横纵坐标分联通块匹配就好。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; int n,m; int xcnt,xbe[1100][1100],ycnt,ybe[1100][1100]; char ss[1100][1100]; bool mp[1100][1100]; void composition() { xcnt=0; for(int i=1;i<=n;i++) { char last=‘#‘;xcnt++; for(int j=1;j<=m;j++) if(ss[i][j]!=‘#‘) xbe[i][j]=xcnt, last=ss[i][j]; else if(last!=‘#‘)xcnt++; } ycnt=0; for(int j=1;j<=m;j++) { char last=‘#‘;ycnt++; for(int i=1;i<=n;i++) if(ss[i][j]!=‘#‘) ybe[i][j]=ycnt, last=ss[i][j]; else if(last!=‘#‘)ycnt++; } memset(mp,false,sizeof(mp)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ss[i][j]==‘*‘) mp[xbe[i][j]][ybe[i][j]]=true; } int match[1100]; bool v[1100]; bool find_muniu(int i) { for(int j=1;j<=ycnt;j++) { if(mp[i][j]==true&&v[j]==true) { v[j]=false; if(match[j]==0||find_muniu(match[j])==true) { match[j]=i; return true; } } } return false; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%s",ss[i]+1); composition(); int ans=0; memset(match,0,sizeof(match)); for(int i=1;i<=xcnt;i++) { memset(v,true,sizeof(v)); if(find_muniu(i)==true)ans++; } printf("%d\n",ans); return 0; }
时间: 2024-10-06 14:09:12