题意:
给一个n×n的矩阵,上面有0和1,然后可以对该矩阵进行行列变换(交换行或者交换列),问最后能否将主对角线全部化为1。
题解:
题目可以转化为是否能找到n个行列均不同的点,然后建二分图,左边为行,右边为列,进行最大匹配,若最后匹配数为n则表示可以找到n个行列均不同的点,即有解。
参考代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=409;
const int MAXM=209*209;
int T,n;
int match[MAXN];
bool used[MAXN];
struct EDGE
{
int v,nxt;
} edge[MAXM*2];
int cnt=0,fir[MAXN];
void addedge(int u,int v)
{
edge[cnt].v=v;
edge[cnt].nxt=fir[u];
fir[u]=cnt++;
}
bool dfs(int u)
{
for(int i=fir[u]; i!=-1; i=edge[i].nxt)
{
int v=edge[i].v;
if(!used[v])
{
used[v]=1;
if(match[v]==-1||dfs(match[v]))
{
match[v]=u;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int sum=0;
for(int i=1; i<=n; i++)
{
memset(used,0,sizeof(used));
if(dfs(i))
sum++;
}
return sum;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
cnt=0;
memset(fir,-1,sizeof(fir));
memset(match,-1,sizeof(match));
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
int x;
scanf("%d",&x);
if(x)
addedge(i,j+n);
}
int ans=MaxMatch();
if(ans==n)
puts("Yes");
else
puts("No");
}
return 0;
}