1 条题解
-
1
具体思路
我们先来找性质。
显然对于下面这样的一个图,一定是无解的。
0 1 0 0 1 1 1 0 0
因为你 这个点你交换行,有 这个点永远跟你同一行,交换列,有 这个点永远跟你同一列。
也就是你永远无法把你想要改变的点放到你想要的位置上。
那就是一个二分图最大匹配问题。
如果一个位置上有黑点,那么就将横坐标向纵坐标连边。
最后跑一遍二分图最大匹配,看最大匹配是不是 即可。
Code
#include<bits/stdc++.h> using namespace std; const int N=4e4+5,M=210; struct edge{ int x,y,pre; }a[2*N]; int last[N],alen; void ins(int x,int y){ a[++alen]=edge{x,y,last[x]}; last[x]=alen; } int mp[M][M]; int match[N],chw[N],tsp; bool query(int x){ for(int k=last[x];k;k=a[k].pre){ int y=a[k].y; if(chw[y]!=tsp){ chw[y]=tsp; if(!match[y]||query(match[y])){ match[y]=x; return 1; } } } return 0; } int main(){ int t;scanf("%d",&t); while(t--){ int n;scanf("%d",&n); alen=1;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&mp[i][j]); if(mp[i][j]){ ins(i,j+n); } } } tsp=0; memset(chw,0,sizeof(chw)); memset(match,0,sizeof(match)); int ans=0; for(int i=1;i<=n;i++){ tsp=i; if(query(i)){ ans++; } } if(ans!=n){ puts("No"); } else puts("Yes"); } return 0; }
- 1
信息
- ID
- 1059
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- (无)
- 递交数
- 23
- 已通过
- 15
- 上传者