문제
그래프의 정점의 집합을 둘로 분할하여, 각 집합에 속한 정점끼리는 서로 인접하지 않도록 분할할 수 있을 때, 그러한 그래프를 특별히 이분 그래프 (Bipartite Graph) 라 부른다.
그래프가 입력으로 주어졌을 때, 이 그래프가 이분 그래프인지 아닌지 판별하는 프로그램을 작성하시오.
입력
입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수 E(1≤E≤200,000)가 빈 칸을 사이에 두고 순서대로 주어진다. 각 정점에는 1부터 V까지 차례로 번호가 붙어 있다. 이어서 둘째 줄부터 E개의 줄에 걸쳐 간선에 대한 정보가 주어지는데, 각 줄에 인접한 두 정점의 번호가 빈 칸을 사이에 두고 주어진다.
출력
K개의 줄에 걸쳐 입력으로 주어진 그래프가 이분 그래프이면 YES, 아니면 NO를 순서대로 출력한다.
예제 입력23 2 1 3 2 3 4 4 1 2 2 3 3 4 4 2 |
예제 출력YESNO |
풀이
우선 문제를 풀기 전에 이분 그래프에 대해 알아보았다.
이분 그래프는 위와 같이 모든 정점을 두 가지 색으로 칠할 때,
간선으로 인접한 모든 정점의 색이 현재 정점의 색과 다른 그래프를 의미한다.
최단 거리와는 상관없이 방문하지 않은 모든 정점을 순환하며 인접한 정점을 비교하면 되기 때문에
DFS나 BFS 두 가지 방법 중 아무거나 선택하여 풀 수 있다.
처음 제출했을 땐 메모리 초과가 떴다.
생각보다 메모리 제한이 빡빡해서 인접 행렬 대신 인접 리스트 방식을 사용했고,
재귀 호출 대신 while문으로 BFS를 호출하는 방식을 택했다.
채점 중 50% 정도에서 틀려서 원인을 알아보았더니
간선의 목록이 주어질 때 맨 처음의 간선에서 시작점을 정했던 것이 문제였다.
모든 정점이 다른 정점과 연결되어있지 않을 수도 있기 때문이었다.
예를 들면 아래 그림과 같다.
BFS 호출이 끝났는데도 색이 칠해지지 않은 정점이 있다면
시작점으로 다시 큐에 넣어주는 방식을 통해 문제를 해결하였다.
from collections import deque
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
def bfs(vt,color):
if colored[vt] == 0:
colored[vt] = color
for i in graph[vt]:
if colored[i] == 0:
# 현재 정점과 다른 색으로 큐에 넣어준다
q.append((i,(color%2+1)))
elif colored[i] == color:
global r
r = "NO"
return
for i in range(int(input())):
v,e = map(int,input().split())
colored = [0 for i in range(v)]
graph = [set() for i in range(v)]
q = deque()
# 인접 리스트 방식으로 그래프 그리기
for i in range(e):
a,b = map(int,input().split())
graph[a-1].add(b-1)
graph[b-1].add(a-1)
r = "YES"
# 아직까지 이분 그래프일 경우에만 실행
while(r=="YES"):
for i in range(v):
for j in graph[i]:
if colored[j] == 0:
q.append((j,0))
break
else:
continue
break
else:
break
while(q):
a,b=q.popleft()
bfs(a,b)
if r=="NO":
break
print(r)
'알고리즘 연습 > DFS와 BFS' 카테고리의 다른 글
[🥈1 / 백준 2468 / 파이썬] 안전 영역 (0) | 2021.09.02 |
---|---|
[🥈2 / 백준 11724 / 파이썬] 연결 요소의 개수 (2) | 2021.08.29 |
[🥇4 / 백준 2206 / 파이썬] 벽 부수고 이동하기 (0) | 2021.08.10 |
[🥈2 / 백준 7562 / 파이썬] 나이트의 이동 (0) | 2021.08.08 |
[🥈1 / 백준 1697 / 파이썬] 숨바꼭질 (0) | 2021.08.07 |