[BOJ 11377] 열혈강호3
[BOJ 11377] 열혈강호3
🔍 문제 분석
- 대표적인 이분 매칭 문제로
N명 중 최대K명은 최대 2개의 일을 담당할 수 있다는 차이점이 있다. - 본 문제는 다음과 같은 과정으로 풀이한다.
- 일반적인 이분 매칭을 수행한다.
- 이분 매칭을 한 번 더 수행하며, 성공한 매칭의 횟수가
K가 되면 종료한다.
💻 코드 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <bits/stdc++.h>
#define fastio cin.tie(0)->ios::sync_with_stdio(0)
using namespace std;
using ll = long long;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvll = vector<vector<ll>>;
using vll = vector<ll>;
using vpi = vector<pi>;
constexpr int MAX = 1'000;
int N, M, K, match[MAX + 1], is_visited[MAX + 1];
vi graph[MAX + 1];
bool dfs(int node) {
for (auto next : graph[node]) {
if (is_visited[next]) continue;
is_visited[next] = true;
if (match[next] == node) continue;
if (match[next] == 0 || dfs(match[next])) {
match[next] = node;
return true;
}
}
return false;
}
int main() {
fastio;
cin >> N >> M >> K;
for (int i = 1; i <= N; ++i) {
int n;
cin >> n;
while (n--) {
int m;
cin >> m;
graph[i].push_back(m);
}
}
for (int i = 1; i <= N; ++i) {
memset(is_visited, 0, sizeof(is_visited));
dfs(i);
}
for (int i = 1; i <= N; ++i) {
if (!K) break;
memset(is_visited, 0, sizeof(is_visited));
if (dfs(i)) K--;
}
int ans = 0;
for (int i = 1; i <= M; ++i) {
ans += !!match[i];
}
cout << ans;
}
📝 코드 설명
if (match[next] == node) continue;
- 두번째 이분 매칭에서 자기 자신이 첫번째 이분 매칭때 담당한 일에 대해서 재귀 호출을 하지 않도록 주의한다.
🔧 트러블 슈팅
📚 참고자료
This post is licensed under CC BY 4.0 by the author.
