Algorithm/그래프

이분 매칭 문제를 해결하는 증가 경로 알고리즘

jhg0406 2020. 2. 23. 22:22
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
//이분 매칭 문제를 해결하는 증가 경로 알고리즘
 
//A와 B의 정점의 개수
int n, m;
//adj[i][j] : Ai와 Bj가 연결되어 있는가?
bool adj[MAX_N][MAX_M];
//각 정점에 매칭된 상대 정점의 번호를 저장한다
vector<int> aMatch, bMatch;
//dfs()의 방문 여부
vector<bool> visited;
//A의 정점인 a에서 B의 매칭되지 않은 정점으로 가는 경로를 찾는다
bool dfs(int a)
{
    if(visited[a]) return false;
    visited[a] = true;
    for(int b = 0; b<m; ++b)
        if(adj[a][b])
            //b가 이미 매칭되어 있다면 bMatch[b]에서 부터 시작해 증가 경로를 찾는다
            if(bMatch[b] == -1 || dfs(bMatch[b]))
            {
                //증가 경로 발견!! a와 b를 매치시킨다
                aMatch[a] = b;
                bMatch[b] = a;
                return true;
            }
    return false;
}
//aMatch, bMatch 배열을 계산하고, 최대 매칭의 크기를 반환한다
int bipartiteMatch()
{
    //처음에는 어떤 정점도 연결되어 있지 않다
    aMatch = vector<int>(n, -1);
    bMatch = vector<int>(m, -1);
    int size = 0;
    for(int start = 0; start < n; ++start)
    {
        visited = vector<bool>(n, false);
        //깊이 우선 탐색을 이용해 start에서 시작하는 증가 경로를 찾는다
        if(dfs(start))
            ++size;
    }
    return size;
}
cs

 

 

 

 

 

 

이분 매칭 문제를 해결하는 증가 경로 알고리즘

이분 매칭이란 이분 그래프에서 최대 매칭을 찾는 문제 입니다.

이분 매칭은 Ford-Fulkerson Algorithm을 응용해 해결할 수 있습니다.

위의 그림처럼 검은색 정점들은 그룹 A, 녹색 정점들은 그룹 B라고 한다면, source는 그룹 A에 붙여주고, sink는 그룹 B에 붙여 주어 그래프 모델링을 할수 있습니다.

모든 간선의 용량은 1로 합니다.

두 그룹 간에 매칭이 1대1 로 이루어지는 점과, 모든 간선의 유량이 1인 이분 매칭 문제의 그래프 특성을 이용한다면, 알고리즘 자체는 다를게 없지만 구현이 간단한 코드를 짤수 있습니다.

 

 

 

 

 

 

시간복잡도

O(|V||E|)

(최대 유량이 V로 정해져 있고, 증가 경로를 한번 찾을때 마다 1씩 최대 유량이 증가하니 f는 |V|가 됩니다. 따라서 O(|V||E|)가 전체 시간 복잡도 입니다.)

 

 

 

 

 

 

프로그래밍 대회에서 배우는 알고리즘 문제해결전략2