这个题乍一看题目,没有思路啊!然后对角线都为1,我下意识认为这题是看这个矩阵是否可逆(能否通过矩阵变换成单位矩阵),但是我只学过代码怎么求逆没学过判断是否可逆,然后我就卡了。。。然后我分析了题,看了知识点是二分图,我就往图方面靠。虽然我们不知道怎么判断可逆,但是如果一个矩阵可逆,那么他对角线一定有数,你没数咋可能变为单位矩阵捏。所以我们只需要判断对角线有没有n个元素就行了。我们就可以进行二分图匹配啦,以行与列作为两个集合。(如果是同一行不同列的,就相当于一夫多妻,他的匹配数只有一个),如果匹配了就加一,数量等于n就yes
#include<bits/stdc++.h>
using namespace std;
int t;
int n,cnt,head[100010];
int x;
vector<int>g[100100];
int st[100010];
int match[100010];
const int mod=1000000007;
struct e{
int next,v;
}edge[100010];
void add(int u,int v)
{
edge[++cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt;
}
bool find(int x)
{
for(int i=head[x];i;i=edge[i].next)
{
int j=edge[i].v;
if(st[j])continue;
st[j]=true;
if(!match[j]||find(match[j]))
{
match[j]=x;
return true;
}
}
return false;
}
int main()
{
cin>>t;
while(t--)
{
memset(match,0,sizeof(match));
cnt=0;memset(head,0,sizeof(head));
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>x;
if(x==1)
{
add(i,j);
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
memset(st,0,sizeof(st));
if(find(i))
ans++;
}
if(ans==n)
printf("Yes\n");
else
printf("No\n");
}
}