【传送门:BZOJ1059】
简要题意:
给出一个01矩阵,相邻的行或者列可以交换,请问是否能通过交换使得从左上角到右下角都为1
题解:
二分图匹配
如果(i,j)为1,那么i向j连边,只要有独立的行与列相匹配,那么这个矩阵就可以通过交换使得从左上角到右下角都为1
参考代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y,next; }a[41000];int len,last[410]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int match[410],chw[410]; bool findmuniu(int x,int t) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(chw[y]!=t) { chw[y]=t; if(match[y]==0||findmuniu(match[y],t)==true) { match[y]=x; return true; } } } return false; } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int x; scanf("%d",&x); if(x==1) ins(i,j+n); } } memset(match,0,sizeof(match)); memset(chw,0,sizeof(chw)); bool bk=true; for(int i=1;i<=n;i++) { if(findmuniu(i,i)==false) { bk=false; break; } } if(bk==true) printf("Yes "); else printf("No "); } return 0; }