문제
- 문제 링크
BOJ 30976 - 사랑의 큐피드
$N$명의 여학생과 $M$명의 남학생에 대한 키 정보가 주어진다.
각 학생에 대한 선호 기준이 주어질 때, 성립될 수 있는 커플의 최대 수를 구해보자.
TL : $1$ sec, ML : $512$ MB
$1 ≤ N, M ≤ 400$ $1 ≤ G_i, B_i, L_i, U_i ≤ 300$ 한 학생이 둘 이상의 커플에 속할 수 없다.
알고리즘 분류
- 이분 매칭 (bipartite_matching)
풀이
여학생 집합과 남학생 집합은 서로 독립적이며, 간선은 서로 다른 집합에 대해서만 향할 수 있다.
즉, 문제의 조건대로 두 집합을 그래프로 모델링할 시 이 그래프는 반드시 이분 그래프의 형태를 띈다.
또한, $N, M ≤ 400$ 이고 최대 매칭 수를 찾아야 한다. 각 매칭은 일대응 대응이므로 이분 매칭을 이용해 약 $O(VE)$에 찾을 수 있다.
$1 ≤ i ≤ N$인 $i$와 $1 ≤ j ≤ M$인 $j$로 이루어지는 모든 $(i, j)$ 쌍에 대해 매칭 가능성을 검사해보자. 만약 $i$와 $j$가 매칭될 가능성이 있다면, $i$$→$$(400+j)$로 간선을 이어주자.
$400$을 더해주는 이유는 두 집합을 서로 다른 숫자집합에 두기 위함이다.
최종적으로 만들어진 이분 그래프에서 이분 매칭을 돌려주면 문제의 정답을 구할 수 있다.
전체 코드
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 | #include<bits/stdc++.h> using namespace std; vector <int> visit(808), assign(808); vector <int> Gr[808]; int Match(int now) { for (int& nxt : Gr[now]) if (!visit[nxt]) { visit[nxt] = 1; if (!assign[nxt] || Match(assign[nxt])) return assign[nxt] = now; } return 0; } int main() { int n, m; cin >> n >> m; int a[4][404]{}; for (int i{}; i < 4; i++) for (int j(1); j <= (i & 1 ? m : n); j++) scanf("%d", &a[i][j]); for (int i(1); i <= n; i++) for (int j(1); j <= m; j++) if (a[2][i] > a[1][j] && a[3][j] < a[0][i]) Gr[i].push_back(400 + j); int ans{}; for (int i(1); i <= n; i++) { visit = vector <int>(808); if (Match(i)) ans++; } cout << ans; } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Platinum)' 카테고리의 다른 글
백준 32583 - Watchdogs (C++) (2) | 2024.11.01 |
---|---|
백준 31222 - 수열과 어렵지 않은 쿼리 (C++) (0) | 2024.08.27 |
백준 30975 - 약간 모자라지만 착한 친구야 (C++) (0) | 2023.12.24 |
백준 30943 - Zatopljenje (C++) (1) | 2023.12.11 |
백준 30512 - 조용히 완전히 영원히 (C++) (1) | 2023.11.20 |