BZOJ 4554 [Tjoi2016&Heoi2016]游戏 ——二分图
出原题,直接二分图匹配即可。
#include <cstdio> #include <vector> #include <cstring> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) vector <int> v[3005]; int n,m,map[55][55],mx,ans; int le[55][55],ri[55][55],vis[3005],linker[3005]; char s[55]; bool dfs(int o) { for (int i=0;i<v[o].size();++i) if (!vis[v[o][i]]){ vis[v[o][i]]=1; if (!linker[v[o][i]]||dfs(linker[v[o][i]])) { linker[v[o][i]]=o; return true; } } return false; } int main() { scanf("%d%d",&n,&m); F(i,1,n) { scanf("%s",s+1); F(j,1,m) switch(s[j]) { case '*': map[i][j]=1;break; case '#': map[i][j]=-1;break; case 'x': map[i][j]=0;break; } } F(i,0,n+1) map[i][0]=map[i][m+1]=-1; F(i,0,m+1) map[n+1][i]=map[0][i]=-1; int cnt=0,con=1; F(i,0,n) F(j,0,m) if (map[i][j]!=-1) con=1,le[i][j]=cnt; else{if (con) ++cnt,con=0;} mx=cnt;cnt=0,con=1; F(j,0,m) F(i,0,n) if (map[i][j]!=-1) con=1,ri[i][j]=cnt; else {if (con) ++cnt,con=0;} F(i,1,n) F(j,1,m) if (map[i][j]==1) v[le[i][j]].push_back(ri[i][j]); F(i,1,mx) { memset(vis,0,sizeof vis); if (dfs(i)) ans++; } printf("%d\n",ans); }