1 条题解
-
0
/* 我们只需要寻找 n 个不同行列的黑格(可以反证自己想下)。 因为我们没法确定在一行中选哪些格子,从而无法直接判断有无解。 直接判断反例: 1 1 0 0 1 1 0 0 1 1 0 0 0 0 1 1 (无解) 这种有多个单位,多个可匹配点,甚至可能有多种匹配方式的问题, 我们考虑使用最大二分图匹配来解决。 将每一行连到每一行上所在的点,点再连到所在的列。 (代码中这里就直接有点就行连列) 如果每一对不同的行都有唯一匹配 (行,列) 的话, 那么就有解。 这样使每个行节点都匹配到一个唯一的列节点, 而且黑点正好处于(行,列)上,满足要求。 */ #include<bits/stdc++.h> using namespace std; const int N = 210; vector<int> G[N]; int tsp, chw[N], match[N]; // 时间戳,该列当前循环有没有被匹配过,列的匹配对象行 bool findmuniu(int x) { for(int y : G[x]) if (chw[y] != tsp) { chw[y] = tsp; if (match[y] == 0 || (findmuniu(match[y]) == 1)) { match[y] = x; return 1; } } return 0; } int main () { ios::sync_with_stdio(false);; cin.tie(0); int T; cin >> T; while (T --) { int n; cin >> n; for (int i = 1; i <= n; i ++) { G[i].clear(); // 多测不清空,亲人两行泪 for (int j = 1; j <= n; j ++) { int x; cin >> x; if (x == 1) { G[i].push_back(j); } } } bool flag = 1; tsp = 0; memset(chw, 0, sizeof(chw)); memset(match, 0, sizeof(match)); for (int i = 1; i <= n; i ++) { tsp ++; if (!findmuniu(i)) { flag = 0; break; } } if (flag == 1) { cout << "Yes" << "\n"; } else { cout << "No" << "\n"; } } return 0; }
- 1
信息
- ID
- 2712
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 30
- 已通过
- 13
- 上传者