一种玄学做法,A了:
每一行每一列都有一个状态,为 no 或 yes,一开始全为 no。
若某一行或某一列只有一个 1,设这个 1 的位置在 (i,j)(即第 i 行第 j 列),则把第 i 行和第 j 列的值全设为 0,并且把第 i 行和第 j 列的状态设为 yes。
重复以上操作直到每一行且每一列的 1 的个数都不等于 1(即只能为 0 或大于 1)。
然后若 (i,j) 这个位置为 1,则把第 i 行和第 j 列的状态设为 yes。
最后判断:每一行每一列的状态都为 yes,则输出 Yes,否则输出 No。
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e2 + 7;
int t, n, flg, ok, fx[N], fy[N];
set<int> x[N], y[N];
main() {
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; ++i) fx[i] = fy[i] = 0, x[i].clear(), y[i].clear();
flg = ok = 1;
for (int i = 1, in; i <= n; ++i) for (int j = 1; j <= n; ++j) {
cin >> in;
if (in) x[i].insert(j), y[j].insert(i);
}
while (ok) {
ok = 0;
for (int i = 1; i <= n; ++i) if (x[i].size() == 1) {
fy[*x[i].begin()] = fx[i] = ok = 1;
for (auto j : y[*x[i].begin()]) if (i != j && x[j].find(*x[i].begin()) != x[j].end()) x[j].erase(x[j].find(*x[i].begin()));
y[*x[i].begin()].clear(), x[i].clear();
}
for (int i = 1; i <= n; ++i) if (y[i].size() == 1) {
fx[*y[i].begin()] = fy[i] = ok = 1;
for (auto j : x[*y[i].begin()]) if (i != j && y[j].find(*y[i].begin()) != y[j].end()) y[j].erase(y[j].find(*y[i].begin()));
x[*y[i].begin()].clear(), y[i].clear();
}
}
for (int i = 1; i <= n; ++i) if (x[i].size()) {
fx[i] = 1;
for (auto j : x[i]) fy[j] = 1;
}
for (int i = 1; i <= n; ++i) flg &= fx[i];
for (int i = 1; i <= n; ++i) flg &= fy[i];
cout << (flg ? "Yes\n" : "No\n");
}
return 0;
}