
문제 풀이
이번 소마 1차 코테 4번 문제를 시간이 부족해 못풀었는데, 오픈채팅방에서 이분매칭이라는 알고리즘 관련된 문제라고 해서 이분매칭에 대해 공부도 할 겸 풀어보았다.
"이분 매칭은 A 집단이 B 집단을 선택하는 방법에 대한 알고리즘입니다." - 나동빈
각 사람이 원하는 항목이 정해져 있을 때 모든 사람 각각이 원하는 항목을 하나씩 선택하여 가장 많이 연결되는 경우를 찾는 문제입니다.

위와 같이 A라는 집단에서 B라는 집단의 항목들에 대한 선호도가 있을 때, 어떻게 해야 A집단과 B집단을 연결할 수 있을까를 푸는 문제라고 생각하면 된다..

문제를 푸는 방식은 맨 위의 사람부터 오른쪽 물건에 대해 연결한다

그리고 2번째 사람이 연결을 하려는데 1번 사람이 1번 물건을 점유하고 있으므로 1번에게 다른 점유할 곳이 없는지 물어봐야한다.
그러면 1번 사람이 2번째 물건으로 연결 대상을 변경할 수 있으므로 True를 반환하고 1번 사람 -> 2번 물건 , 2번 사람 -> 1번 물건을 점유하게 된다.
이런식으로 쭉쭉 연결해서 최대 매칭 수를 구하면 되는 문제이다
연결 대상을 변경할 수 있는지 문의하는 과정을 확인해보자
vector<int> per[1002]; //어떤 사람이 어떤 책을 선호하는지 저장
//1번 사람이 1, 2, 3번 책을 선호한다고 가정
// per[1] = {1,2,3}이 저장됨.
int nd[1002]; // 책을 어떤 사람이 점유 했는지! 저장
bool c[1002]; //책이 점유 되었는지
bool dfs(int x) {
for (int i = 0; i < per[x].size(); i++) {
int t = per[x][i];
if (c[t] == true)
continue;
c[t] = true;
if (nd[t] == 0 || dfs(nd[t])) { //책을 점유한 사람이 없거나 / 점유한 사람이 다른 책을 선택할 수 있는 경우
nd[t] = x;
return true;
}
}
return false;
}
이 문제에서 핵심은 dfs함수 안의 if(nd[t] == 0 || dfs(nd[t])) 부분이다!
nd[t] == 0 : 책을 점유한 사람이 없는 경우 책을 x라는 사람이 점유
dfs(nd[t]) : 책을 점유한 사람이 있는 경우 이 책 말고 다른 책을 점유할 수 있는지 문의
위의 bool dfs(int x ) 함수를 통해 이분 매칭을 수행할 수 있다!
소스 코드
#include <iostream>
#include <vector>
using namespace std;
vector<int> per[1002];
int nd[1002]; // 책을 어떤 사람이 점유 했는지! 저장
bool c[1002]; //책이 점유 되었는지
bool dfs(int x) {
for (int i = 0; i < per[x].size(); i++) {
int t = per[x][i];
if (c[t] == true)
continue;
c[t] = true;
if (nd[t] == 0 || dfs(nd[t])) {
nd[t] = x;
return true;
}
}
return false;
}
int main() {
int t;
cin >> t;
for (int i = 0; i < t; i++) {
int n, m;
cin >> n >> m;
for (int j = 1; j <= m; j++) {
int a, b;
cin >> a >> b;
for (int t = a; t <= b; t++) {
per[j].push_back(t);
}
}
fill(nd, nd + 1001, 0);
int ans = 0;
for (int j = 1; j <= m; j++)
{
fill(c, c + 1001, false);
if (dfs(j))
ans++;
}
cout << ans << '\n';
for (int t = 1; t <= m; t++) {
per[t].clear();
}
}
return 0;
}
'알고리즘' 카테고리의 다른 글
[백준] 3190번 뱀 Python 문제풀이 (2) | 2024.04.18 |
---|---|
[프로그래머스] 하노이의 탑 C++ 문제풀이 (0) | 2024.02.27 |
[프로그래머스] 두 원 사이의 정수 쌍 C++ 문제풀이 (0) | 2024.02.22 |
[프로그래머스] 달리기 경주 C++ 문제풀이 (0) | 2024.02.13 |
[백준] 1753번 최단경로 구하기 C++ 문제풀이 (0) | 2024.02.04 |