티스토리 뷰

알고리즘

백준 1707 - 파이썬

취뽀가자!! 2023. 7. 7. 23:16

https://www.acmicpc.net/problem/1707

 

1707번: 이분 그래프

입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V와 간선의 개수 E가 빈 칸을 사이에

www.acmicpc.net

이분 그래프는 인접한 노드끼리 서로 다른 집합에 넣을 수 있다면 이분 그래프이다.

아래의 경우는 서로 다른 집합에 속하므로 이분 그래프가 아니다.

출처: 위와 동일

이분 그래프는 처음 접해보는 개념이기도 하고, 풀이 방법도 떠오르는게 없어 구글링을 해봤다. 각 코드의 출처는 제목에 연결해 두겠다.

BFS 1

import sys
from collections import deque
input = sys.stdin.readline

def bfs(start,group):
  q = deque([start])
  visited[start] = group

  while q:
    x = q.popleft()
    for i in graph[x]:
      if not visited[i]:
        q.append(i)
        # 그룹을 1과 -1으로 나누며, 인접 노드는 -1을 곱하여 그룹 구분
        visited[i] = visited[x] * -1 
        # 현재 노드와 인접 노드의 그룹이 같다면 이분 그래프가 아님
      elif visited[i] == visited[x]:
        return False

  return True

for _ in range(int(input())):
  v,e = map(int,input().split())
  graph = [[] for i in range(v+1)]
  visited = [False] * (v+1)

  for _ in range(e):
    a,b = map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)

  for i in range(1,v+1):
    if not visited[i]:
      result = bfs(i,1)
      if not result:
        break

  print("YES" if result else "NO")

BFS 2

from collections import deque
import sys
input = sys.stdin.readline

k = int(input())

def bfs(graph,start):
  q = deque()
  q.append(start)
  if visited[start] == 0:
    visited[start] = 1
  while q:
    v = q.popleft()
    color = visited[v]

    for i in graph[v]:
      if visited[i] == 0:
        q.append(i)
        if color == 1:
          visited[i] = 2
        else:
          visited[i] = 1
      elif visited[i] == 1:
        if color == 1:
          print("NO")
          return False

      elif visited[i] == 2:
        if color == 2:
          print("NO")
          return False

  return True


for i in range(k):
  flag = 0
  v,e = map(int, input().split())
  graph = [[] for _ in range(v+1)]
  visited = [0] * (v+1)
  for j in range(e):
    a,b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)

  for k in range(1, v+1):
    if not bfs(graph,k):
      flag = 1
      break
  if flag == 0:
    print("YES")

DFS

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)

k = int(input())

def dfs(start,visited,graph,group):
  visited[start] = group

  for v in graph[start]:
    if visited[v] == 0:
      result = dfs(v, visited, graph, -group)

      if not result:
        return False

    else:
      if visited[v] == group:
        return False

  return True

for _ in range(k):
  v,e = map(int, input().split())
  graph = [[] for _ in range(v+1)]
  visited = [0] * (v+1)
  for _ in range(e):
    a,b = map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)

  for i in range(1, v+1):
    if visited[i] == 0:
      result = (dfs(i, visited, graph, 1))
      if not result:
        break

  print("YES") if result else print("NO")

DFS로 푼 문제도 group을 -1과 1로 나눠 구분하는 방식은 똑같다. 

 

느낀점

처음에 문제를 읽고 어떻게 풀어야 하나 막막했는데 다른 사람들이 정리해 둔 개념과 코드를 천천히 읽어보니 개념도 이해됐고, 코드도 이해되었다. 이분 그래프의 아주 기본적인 문제인거 같으니 머릿속에 잘 기억해 둬야 되겠다.

'알고리즘' 카테고리의 다른 글

백준 1744 - 파이썬  (0) 2023.07.21
백준 13459 - 파이썬  (0) 2023.07.11
백준 12851 - 파이썬  (0) 2023.07.06
백준 16234 - 파이썬  (0) 2023.07.04
백준 1389 - 파이썬  (0) 2023.06.25
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
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
글 보관함