题目:http://www.qscoj.cn/#/problem/show/1963
将被隔开的当作新的行或者新的列
对行和列进行二分图匹配
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; const int N=1e5+5; int head[N],nt[N],to[N],match[N]; bool use[N]; char a[60][60]; int b[60][60]; int n,m,s1,s2,tot; void addedge(int u,int v) { nt[++tot]=head[u]; to[tot]=v; head[u]=tot; } bool dfs(int x) { for(int i=head[x];i!=-1;i=nt[i]) { int u=to[i],w=match[u]; if (use[u]) continue; use[u]=1; if (w<0||dfs(w)) { match[u]=x; return 1; } } return 0; } int found() { int res=0; memset(match,-1,sizeof(match)); for(int i=1;i<=s1;i++) { memset(use,0,sizeof(use)); if (dfs(i)) res++; } return res; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s",a[i]); tot=0; memset(head,-1,sizeof(head)); s1=1; int ans=0; for(int i=1;i<=n;i++) { for(int j=0;j<m;j++) { if (a[i][j]=='+') s1++; if (a[i][j]=='o') {b[i][j]=s1;ans++;} } s1++; } s2=1; for(int j=0;j<m;j++) { for(int i=1;i<=n;i++) { if (a[i][j]=='+') s2++; if (a[i][j]=='o') addedge(b[i][j],s2); } s2++; } printf("%d ",ans-found()); return 0; }