이분 매칭 문제를 엄청 오랜만에 풀어봤다.
https://en.wikipedia.org/wiki/Matching_(graph_theory)
http://koosaga.com/18
http://1ambda.github.io/algorithm/algorithm-part2-5/
위 링크에 많은 설명이 있고, 읽지는 않았다.
이 문제를 풀이한 방법은 아주 기초적인 DFS 를 이용한 O(V * E) 이다.
오늘은 시간이 없어서 이론보다는 구현을 목적으로 공부했다.
풀이 방법
1. 사람을 한명씩 dfs 로 연결할 수 있는 일을 잡는다.
2. 이미 연결돼있는 선이라면 그 선에 연결된 사람이 다른 일을 잡을 수 있는지 확인한다.
3. 반복
4. 끝
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <vector> | |
/** | |
* https://www.acmicpc.net/problem/11375 | |
* BOJ 백준온라인져지 11375 열혈강호 풀이 | |
*/ | |
using namespace std; | |
vector<vector<int> > adj; | |
vector<int> match; | |
vector<bool> visited; | |
int workCount; | |
bool dfs (int here) { | |
if (visited[here]) return false; | |
visited[here] = true; | |
for (int there = 1; there <= workCount; there++) { | |
if (adj[here][there]) { | |
if (match[there] == -1 || dfs(match[there])) { | |
match[there] = here; | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
int main () { | |
int personCount; | |
scanf("%d%d", &personCount, &workCount); | |
adj.resize(personCount + 1); | |
for (int i = 1; i <= personCount; i++) { | |
adj[i].resize(workCount + 1); | |
int length; | |
scanf("%d", &length); | |
for (int j = 0; j < length; j++) { | |
int work; | |
scanf("%d", &work); | |
adj[i][work] = 1; | |
} | |
} | |
int result = 0; | |
match = vector<int>(workCount + 1, -1); | |
for (int i = 1; i <= personCount; i++) { | |
visited = vector<bool>(personCount + 1, false); | |
if (dfs(i)) result++; | |
} | |
printf("%d", result); | |
} |
'IT > 알고리즘' 카테고리의 다른 글
BOJ 백준온라인져지 11376 열혈강호 2 풀이 (0) | 2018.01.27 |
---|---|
BOJ 백준온라인져지 2822 점수 계산 풀이 (0) | 2018.01.25 |
BOJ 백준온라인져지 14502 연구소 풀이 (0) | 2018.01.14 |
BOJ 백준온라인져지 4485 녹색 옷 입은 애가 젤다지? 풀이 (0) | 2018.01.13 |
BOJ 백준온라인져지 1261 알고스팟 풀이 Raw (0) | 2018.01.11 |