백준(BOJ) 문제 풀이

백준 1298번 문제(노트북의 주인을 찾아서) 파이썬(Python) 풀이 [로밍맨]

로밍맨 2021. 7. 2. 22:57
728x90
반응형

문제 링크

www.acmicpc.net/problem/1298

 

1298번: 노트북의 주인을 찾아서

어느 날 모든 학생들은 한 명이 한개의 노트북을 가지고 공부하던 도중, 자리를 바꾸다가 그만 노트북이 뒤섞이고 말았다. 대다수의 학생들은 자신의 노트북을 잘 알고 있어서 자신의 노트북을

www.acmicpc.net

 

정답 코드는 아래와 같습니다.

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
44
45
46
47
48
49
50
51
52
53
54
55
import sys
import collections
import math
 
SOURCE = 0
SINK = 201
VMAX = 202
HUND = 100
 
def bfs(flow, capacity, source, sink):
  parent = [-1* VMAX
  q = collections.deque([source])
  parent[source] = source
  while len(q) != 0:
    item = q.popleft()
    for i in range(VMAX):
      if parent[i] == -1 and capacity[item][i] - flow[item][i]:
        q.append(i)
        parent[i] = item
  return parent
 
def maxFlow(capacity, source, sink):
  flow = [[0* VMAX for _ in range(VMAX)]
  rst = 0
  while True:
    parent = bfs(flow, capacity, source, sink)
    if parent[sink] == -1:
      return rst
    #minimum
    node = sink
    m = math.inf
    while node != source:
      m = min(m, capacity[parent[node]][node] - flow[parent[node]][node])
      node = parent[node]
    #add
    rst += m
    node = sink
    while node != source:
      flow[parent[node]][node] += m
      flow[node][parent[node]] -= m
      node = parent[node]
 
def solve():
  N, M = map(int, sys.stdin.readline().rstrip().split())
  graph = [[0* VMAX for _ in range(VMAX)]
  for _ in range(M):
    a, b = map(int, sys.stdin.readline().rstrip().split())
    graph[a][b+HUND] += 1
  for i in range(1, HUND+1):
    graph[SOURCE][i] += 1
    graph[i+HUND][SINK] += 1
  print(maxFlow(graph, SOURCE, SINK))
 
solve()
 
cs

 

728x90

 

전형적인 이분 매칭 문제로, 최대 유량 문제로 변환하여 풀 수 있습니다.

이분 매칭 문제와 최대 유량 문제는 아직도 많은 연구자들이 연구하고 있는 분야이며, 불과 몇 년 전에도 새로운 알고리즘이 개발되었습니다.

실제 응용되는 분야가 굉장히 많은 알고리즘임에도 불구하고, 일반적인 기업들의 코딩테스트에는 잘 등장하지 않는데요.

그 이유는 사실상 풀이를 외워야 하고, 최대 유량 알고리즘을 활용하지 않는 분야에서는 이 알고리즘을 알아야 할 이유도 없기 때문입니다.

다시 말해서 중요하고 응용 가능성이 매우 높지만, 일반적인 개발자들에게는 특별히 많이 사용되지 않기 때문이라고 할 수 있습니다.

최대 유량 문제를 풀기 위한 알고리즘은 매우 많지만 실제 대회나 코테에서는 Edmonds-Karp 알고리즘 정도만 사용해도 보통 풀리기 때문에 저는 보통 Edmonds-Karp 알고리즘을 사용합니다.

 

풀이는 아래 영상을 참고 바랍니다.

www.youtube.com/watch?v=RHyFfFUXHZE  

 

저작권 라이선스: CC BY (출처만 표시하면 자유롭게 이용 가능)

728x90
반응형