////
Search

이분그래프

소스코드

import sys from collections import deque input = sys.stdin.readline K = int(input().strip()) # 테스트 케이스 수 # 탐색하며 이분 그래프인지 아닌지 판별하는 함수 def bfs(graph, group, node): queue = deque([node]) while queue: now = queue.popleft() # 인접노드 확인 for neighbor in graph[now]: if group[neighbor] == None: group[neighbor] = 1 - group[now] queue.append(neighbor) elif group[neighbor] == group[now]: # 방문했던 노드가 인접노드와 색깔까지 동일하다면 -> 이분 그래프 X return False return True for _ in range(K): V, E = map(int, input().strip().split()) graph = [[] for _ in range(V + 1)] for _ in range(E): u,v = map(int, input().strip().split()) graph[u].append(v) graph[v].append(u) result = "YES" group = [None] * (V + 1) for i in range(1, V + 1): if group[i] == None: if not bfs(graph, group, i): result = "NO" break print(result)
Python
복사

풀이

그래프를 그려 RB트리를 색칠하는 것처럼 하나하나 노드의 색깔을 입혀보다보면, 예제 입력1에서 2번째 케이스에 대해 NO가 나온다는 것을 눈으로 확인할 수 있습니다. AI에게 물어보니 홀수 개의 사이클이 형성되면 이분 그래프가 될 수 없다고 하더라구요. 아무튼 그냥 색깔을 반전시키며 다음 노드로 진출하다가 인접 노드끼리 색이 동일하면 이분 그래프가 될 수 없다는 것을 확인할 수 있습니다.
처음에는 단순하게 큐의 원소로 (노드 번호, 색깔)을 넣어서 이전 노드와만 색깔을 비교하는 형태로 사용하려고 했습니다. 왜 그랬을까요? 이전 노드와만 비교해야하는게 아니라 모든 인접노드와 비교해야하는데 말입니다.
전체 노드들의 색깔 정보를 포함한 group 리스트를 생성합니다.
연결 그래프(특정한 두 정점이 꼭 이어져있으리라 보장되는 그래프)가 아닐 수도 있음을 주의해야합니다. 그래서 모든 노드를 순회하면서 아직 그룹이 결정되지 않은(=방문하지 않은) 노드에 대해서 BFS 함수를 실행해 그룹을 지정하고 이분 그래프를 만들어내는지 체크합니다.
bfs함수의 결과가 True면 계속해서 다음 노드를 탐색합니다.
bfs함수의 결과가 False면 이분그래프가 아니라는 소리이므로 곧바로 반복문을 종료하고 결과를 “NO”로 수정합니다.
BFS 함수는 다음 과정을 갖습니다 :
현재 노드의 인접 노드를 확인합니다
만약 방문한 적 없는 인접 노드라면(그룹이 지정된 적 없다면), 현재 노드의 그룹과 반대 그룹으로 지정하고 큐에 삽입합니다.
만약 방문한 적 있는 인접 노드라면(그룹이 지정된 적 있다면), 현재 노드의 그룹과 동일한지 확인합니다
만약 인접 노드와 현재 노드의 그룹이 동일하다면 이분 그래프가 아니라는 소리입니다.
결과 출력하면 끝!!

회고

아직 자료구조를 뭘 써야겠다를 확신을 갖고 사용한다는 느낌을 잘 못 받는 경우가 왕왕 있다고 생각합니다. 왜 그럴까요? 지속적으로 복기해보면서 특정 상황에 대해 어떤 자료구조를 기반으로 풀어내야겠다는 감각을 늘려나가야할 듯 합니다.