rt,这是错误代码,但是能过:
#include <bits/stdc++.h>
#define debug(x) (cout << #x << " " << x << "\n")
using namespace std;
using ll = long long;
const int N = 1005;
int n, m, ans, match[N];
bool vis[N];
vector<int> nbr[N];
bool hungary(int cur) {
for (auto nxt : nbr[cur]) if (!vis[nxt]) {
vis[nxt] = 1;
if (!match[nxt] || hungary(match[nxt])) {
match[nxt] = cur;
return 1;
}
}
return 0;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 1, u, v; i <= m; i++) {
cin >> u >> v, ++ u, ++ v;
nbr[u].emplace_back(v);
}
for (int i = 1; i <= n; i++) {
fill(vis + 1, vis + 1 + n, 0);
ans += hungary(i);
}
cout << n - ans;
return 0;
}
由于不知道一组关系中哪个是男生,哪个是女生,所以「不能直接连单向边」。
解决方案是染色,还得标记哪些人参与了舞会。这是正确代码:
#include <bits/stdc++.h>
#define debug(x) (cout << #x << " " << x << "\n")
using namespace std;
using ll = long long;
const int N = 1005;
int n, m, ans, match[N], col[N];
bool vis[N], bk[N];
vector<int> nbr[N], nbr_[N];
void dfs(int cur, int c) {
col[cur] = c;
for (auto nxt : nbr[cur]) if (!~col[nxt]) {
dfs(nxt, c ^ 1);
}
}
bool hungary(int cur) {
for (auto nxt : nbr[cur]) if (!vis[nxt]) {
vis[nxt] = 1;
if (!match[nxt] || hungary(match[nxt])) {
match[nxt] = cur;
return 1;
}
}
return 0;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 1, u, v; i <= m; i++) {
cin >> u >> v, ++ u, ++ v;
nbr[u].emplace_back(v);
nbr[v].emplace_back(u);
bk[u] = bk[v] = 1;
}
fill(col + 1, col + 1 + n, -1);
for (int i = 1; i <= n; i++) if (bk[i] && !~col[i]) {
dfs(i, 0);
}
for (int i = 1; i <= n; i++) if (bk[i] && !col[i]) {
for (auto nxt : nbr[i]) nbr_[i].emplace_back(nxt);
}
for (int i = 1; i <= n; i++) if (bk[i] && !col[i]) {
fill(vis + 1, vis + 1 + n, 0);
ans += hungary(i);
}
cout << n - ans;
return 0;
}
在本题帖子“建议降绿”中,lz 提到「1.图论建模没有难度,可以直接连」。
但是,这显然是矛盾的!!!!!!!!
故 建议加强数据 & 对帖子”建议降绿“提出异议。