topic:
analysis:
Like this, two colors, or square, so small range of data, the preferred bipartite graph matching.
By analyzing the problem, we can know that no matter how the exchange, the number of row or column 1 will not change.
The last requirement is that at least each row and each column to share a 1 ,.
One can imagine:
Row position row
Row by row to the position 1 connected edge, so as to match a row.
Removing the intermediate point is a bipartite graph matching, if and only if the number of matches == n legitimate.
#include<bits/stdc++.h> using namespace std; #define N 405 #define M 50005 #define ri register int int read() { int x=0,fl=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') fl=-1; ch=getchar(); } while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*fl; } int a[N][N],n,ans=0,head[M],nex[M],to[M],tot=0,match[M],vis[M],Ti=0; void add(int a,int b) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; } bool dfs(int u) { if(vis[u]==Ti) return false; vis[u]=Ti; for(ri i=head[u];i;i=nex[i]){ int v=to[i]; if(!match[v] || dfs(match[v])){ match[v]=u; match[u]=v; return true; } } return false; } void init() { for(ri i=0;i<=max(tot,2*n);++i) head[i]=to[i]=nex[i]=match[i]=vis[i]=0; tot=0; Ti=0; ans=0; } int main() { freopen("f.in","r",stdin); freopen("f.out","w",stdout); int T=read(); while(T--){ init(); n=read(); for(ri i=1;i<=n;++i){ for(ri j=1;j<=n;++j){ a[i][j]=read(); if(a[i][j]) add(i,j+n),add(j+n,i);// } } for(ri i=1;i<=n;++i){ Ti++; ans+=dfs(i); } if(ans==n) printf("Yes\n"); else printf("No\n"); } return 0; } /* 6 2 0 0 0 1 3 0 0 1 0 1 0 1 0 0 4 0 0 0 1 0 0 1 0 1 0 0 0 0 1 1 0 */
topic:
analysis:
Without limiting barriers, directly on a question along the lines of, even rows to columns side (only put a line, one can only put a), running side bipartite graph matching.
More obstacles for the line, the equivalent of a line divided into many parts, each part can put a column also empathy.
After each section of the line will be split renumbered, you can connect with the column side.
The last answer is the maximum number of matches.
( I use the network stream )
#include<bits/stdc++.h> using namespace std; #define N 205 #define M 1000005 #define ri register int int n,m,a[N][N],h[N][N],l[N][N],id[N][N],s,t; char ss[N]; int cost[M],lev[M],head[M],nex[M<<1],to[M<<1],tot=1,hang,lie; queue<int> q; void add(int a,int b,int ww) { //printf("%d %d %d\n",a,b,ww); to[++tot]=b; nex[tot]=head[a]; head[a]=tot; cost[tot]=ww; to[++tot]=a; nex[tot]=head[b]; head[b]=tot; cost[tot]=0; } bool bfs() { memset(lev,-1,sizeof(lev)); lev[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=nex[i]) { int v=to[i]; if(cost[i]!=0&&lev[v]==-1) lev[v]=lev[u]+1,q.push(v); } } if(lev[t]!=-1) return true; return false; } int dfs1(int u,int flow) { if(u==t) return flow; int ret=flow; for(int i=head[u];i!=-1;i=nex[i]) { if(ret<=0) break; int v=to[i]; if(cost[i]&&lev[u]+1==lev[v]) { int k=dfs1(v,min(cost[i],ret)); ret-=k; cost[i]-=k; cost[i^1]+=k; } } return flow-ret; } void dinic() { int ans=0; while(bfs()) ans+=(dfs1(s,lie)); printf("%d\n",ans); } int main() { freopen("chess.in","r",stdin); freopen("chess.out","w",stdout); scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); s=0,t=n*m*4; int cnt=0; for(ri i=1;i<=n;++i){ scanf("%s",ss); for(ri j=1;j<=m;++j) a[i][j]=ss[j-1]-'0',id[i][j]=++cnt; } hang=0,lie=0; for(ri i=1;i<=n;++i) for(ri j=1;j<=m;++j) if(j==1) h[i][j]=a[i][j] ? 0 : ++hang; else if(a[i][j]==a[i][j-1] && a[i][j]==0) h[i][j]=h[i][j-1]; else if(a[i][j-1]==1 && a[i][j]==0) h[i][j]=++hang; else h[i][j]=0; for(ri j=1;j<=m;++j) for(ri i=1;i<=n;++i) if(i==1) l[i][j]=a[i][j] ? 0 : ++lie; else if(a[i][j]==a[i-1][j] && a[i][j]==0) l[i][j]=l[i-1][j]; else if(a[i-1][j]==1 && a[i][j]==0) l[i][j]=++lie; else l[i][j]=0; /*for(ri i=1;i<=n;++i){ for(ri j=1;j<=m;++j) cout<<h[i][j]<<" "; cout<<endl; } printf("lie:%d\n",hang);*/ for(ri i=1;i<=n;++i) for(ri j=1;j<=m;++j) if(a[i][j]==0) add(l[i][j]+n*m,id[i][j],1),add(id[i][j],h[i][j]+2*n*m,1); for(ri i=1;i<=lie;++i) add(s,i+n*m,1); for(ri i=1;i<=hang;++i) add(i+n*m*2,t,1); dinic(); } /* 3 3 010 001 010 */