구글 코드 잼 연습 문제를 오랜만에 풀어보았다. 사실 작년 12월 초에 풀다가 잘 안 풀려서 2달 정도 손을 놓았다가 다시 풀었다. 알고 보면 굉장히 간단한 문제인데, 접근을 엉뚱하게 해서 풀이만 복잡해지고 제대로 된 결과를 구할 수 없었다.
문제를 간단하게 서술해보자. 서로 함께 있으면 문제를 일으키는 쌍에 대한 정보를 준다. 과연 문제가 없이 사람끼리 모이도록 전체 사람들을 두 그룹으로 나누는 것이 가능한가?
접근 방법은 다음과 같다. 각 사람을 vertex로 하고, 서로 문제를 일으키는 사람 간에 edge가 존재하는 그래프를 생각한다. 그리고 각 vertex를 둘 중 하나의 색으로 칠하는데, edge로 이어진 두 vertex는 서로 다른 색이어야 한다.
처음에는 모든 vertex에 색이 없다. 칠해지지 않은 한 vertex를 선택하고, 그 vertex를 시작으로 BFS를 통해 연결된 vertex를 조사한다. 이때 이 vertex는 1) 색이 없는 상태 2) 연결될 수 없는 같은 색이 있는 상태 3) 연결될 수 있는 다른 색이 있는 상태 중 하나이다. 1)의 경우에는 다른 색을 칠하고 그것과 연결된 vertex들을 조사하게 한다. 2)의 경우 두 그룹으로 나눌 수 없다는 결론을 낸다. 3)의 경우 이 vertex에 대한 조사는 중단한다. (이미 이것과 연결된 vertex에 대한 조사는 끝났기 때문)
BFS 과정에서 찾아지는 vertex가 없으면, 칠해지지 않고 남아 있는 vertex로 앞의 작업을 반복한다. 문제없이 모든 vertex를 칠할 수 있으면 두 그룹으로 나눌 수 있다.
'[아는게 힘이다] > [프로그래밍]' 카테고리의 다른 글
연결 리스트(Linked List) 부분 뒤집기(reverse) (0) | 2016.03.14 |
---|---|
부분합(subsum) 문제 관련 (0) | 2016.02.25 |
[C] 몇 가지 코딩 실수 (2) | 2012.05.14 |
[C++/ACM] 820 Internet Bandwidth (0) | 2010.05.16 |