11375번: 열혈강호
강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있다. 각 직원은 한 개의 일만 할 수 있고, 각각
www.acmicpc.net
3일 전에 틀리고 '블로그에 옮기면서 다시 한번 봐야지' 했는데 이제야 쓴다.
분명 이분 매칭 문제를 푼 기억이 있는데, 문제를 보고 이분 매칭을 떠올리지 못했다.
이분 매칭을 잘 설명한 글
[알고리즘] 이분 매칭 알고리즘 (Bipartite Matching)
이분 매칭 알고리즘 (Bipartite Matching) 두 개의 정점 그룹이 존재할 때 모든 간선(경로)의 용량이 1이면서 양쪽 정점이 서로 다른 그룹에 속하는 그래프를 이분 그래프(Bipartite Graph)라고 말합니다.
yjg-lab.tistory.com
이분 매칭(Bipartite Matching)
이번에 올릴 글은 네트워크 플로우 개념의 연장...은 아닌 것 같고, 유량 그래프의 아주 특수하면서 메이저...
blog.naver.com
bool dfs(int worker) {
if (visited[worker]) {
return false;
}
visited[worker] = true;
for (int job : graph[worker]) {
if (assigned_to[job] == 0 || dfs(assigned_to[job])) {
assigned_to[job] = worker;
return true;
}
}
return false;
}
이미 방문했던 정점(직원)이라면 false return
내가(현재 dfs를 진행하는 직원이) 할 수 있는 일의 목록을 순회하며 일을 하나씩 살펴본다.
1. 아직 어떤 직원에게도 할당되지 않은 경우
2. 이미 하기로 한 직원(B)이 있지만, 해당 직원(B)이 다른 일을 맡을 수 있어 내가 해도 되는 경우
두 경우에 해당한다면 일을 나에게 할당하고 true를 return
어떤 일도 내가 맡을 수 없다면(어떤 일도 나에게 할당될 수 없다면) false return
코드
#include <iostream>
#include <vector>
#include <cstring>
int N, M;
std::vector<int> graph[1001];
bool visited[1001];
int assigned_to[1001];
bool dfs(int worker) {
if (visited[worker]) {
return false;
}
visited[worker] = true;
for (int job : graph[worker]) {
if (assigned_to[job] == 0 || dfs(assigned_to[job])) {
assigned_to[job] = worker;
return true;
}
}
return false;
}
int main() {
std::cin >> N >> M;
int jobs, job;
for (int i = 1; i < N + 1; i++) {
std::cin >> jobs;
for (int j = 0; j < jobs; j++) {
std::cin >> job;
graph[i].push_back(job);
}
}
int answer = 0;
for (int i = 1; i < N + 1; i++) {
std::memset(visited, false, sizeof(visited));
if (dfs(i)) {
answer++;
}
}
std::cout << answer << "\n";
return 0;
}
'PS > BOJ' 카테고리의 다른 글
BOJ 11376 : 열혈강호 2 [C++] (0) | 2024.02.11 |
---|---|
BOJ 2758 : 로또 [C++] (1) | 2024.02.06 |
BOJ 16202 : MST 게임 [C++] (0) | 2024.01.31 |
BOJ 16206 : 롤케이크 [C++] (0) | 2024.01.30 |
BOJ 1106 : 호텔 [C++] (0) | 2023.01.16 |