https://github.com/Dev-Guccin
Guccin
https://github.com/Dev-Guccin
전체 방문자
오늘
어제
  • 분류 전체보기 (172)
    • 알고리즘 (140)
    • 삽질방지 (13)
    • SystemHacking (1)
    • 일상 (4)
    • 개발 (8)
    • 스프링 부트 REST API 개발일지 (5)
    • JPA (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 다이나믹프로그래밍
  • python3
  • 다이나믹 프로그래밍
  • DFS
  • 이분탐색
  • 재귀
  • 이분 탐색
  • 재귀함수
  • 그리디
  • MST
  • 최소힙
  • BFS
  • 파이썬
  • 백준
  • 그래프
  • 최대공약수
  • 백트래킹
  • 스택
  • 프로그래머스
  • Python
  • LIS
  • 큐
  • counter
  • 유니온 파인드
  • 유클리드호제법
  • DP
  • 최단경로
  • 다익스트라
  • heapq
  • 12015

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
https://github.com/Dev-Guccin

Guccin

알고리즘

백준 1707 python 풀이 (이분 그래프, BFS)

2021. 7. 11. 00:34

일단 처음에 문제를 읽고는 생각보다 쉽다고 느꼈다. 단순히 BFS로 탐색하면서 이전 값이랑 비교하면 되겠구만 했다. 그런데 구현하는데 상당히 애를 먹었고, 시간초과가 떠서 오랜 삽질 중이다.

우선 시간초과 코드는 아래와 같다.

from collections import deque
import sys
input = sys.stdin.readline
T = int(input())

def BFS(v,e,color, d,q):
    color[q[0]] = 1
    visited = [0 for i in range(v+1)]
    while q:
        target = q.popleft()
        visited[target] = 1
        targets = d[target]
        for t in targets:
            if visited[t] == 0:
                q.append(t)
            else:
                continue
            if color[t] == -1: #안칠해짐
                color[t] = color[target]^1
            else: #이미 칠해짐
                if color[t] == color[target]:#이분 그래프 아님
                    return "NO"
    return "YES"

for _ in range(T):
    v,e = map(int, input().split())
    d = {}
    color = [-1 for i in range(v+1)]
    q = deque([])
    for i in range(e):
        tmp=list(map(int,input().split()))
        if i == 0:
            q.append(tmp[0])
        if tmp[0] not in d: # 없는경우
            d[tmp[0]] = [tmp[1]]
        else:
            d[tmp[0]].append(tmp[1])
        if tmp[1] not in d:
            d[tmp[1]] = [tmp[0]]
        else:
            d[tmp[1]].append(tmp[0])
    print(BFS(v,e,color, d, q))

 

그래서! 고수의 코드를 쓱 훔쳐보고 와서 다시 코딩을 진행했다.

기존의 코드는 dictionary에 값을 넣고 하나씩 방문하며 visited와 color배열을 돌며 검증을 한다. 문제는 dictionary에 넣는 과정에서 매번 dictinary의 key값들을 돌며 확인하기 때문에 시간복잡도가 오래 걸린다.

그러나 새로운 코드는 배열에 값들을 빠르게 집어넣고 첫 노드부터 방문하여 이분 그래프인지 확인한다.

따라서 BFS의 내부 로직은 비슷하지만 초기에 그래프를 세팅하는 과정에서 속도 차이가 많이 나는듯 하다.

구현한 코드는 아래와 같다.

from collections import deque
import sys
input = sys.stdin.readline
T = int(input())

def BFS(Map, target, visited):
    visited[target] = 1
    q = deque([target])
    while q:
        target = q.popleft()
        targets = Map[target]
        for t in targets:
            if visited[t] == 0: #방문 x
                visited[t] = -visited[target]
                q.append(t)
            else: #방문 했으면 비교
                if visited[t] == visited[target]:#이분 그래프 아님
                    return "NO"
    return "YES"
for _ in range(T):
    v,e = map(int, input().split())
    Map = [[] for i in range(v+1)]
    visited = [0  for i in range(v+1)]
    for i in range(e):
        a,b=map(int,input().split())
        Map[a].append(b)
        Map[b].append(a)
    flag = True
    for i in range(1,v+1):
        if visited[i] == 0:
            if BFS(Map, i, visited) == "NO":
                flag = False
                break
    if flag == True:
        print("YES")
    else:
        print("NO")

결론은 그래프를 초기에 어떻게 세팅하는지 얼마나 빠르게 세팅하는지도 굉장히 중요하다.

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

백준 1987 파이썬 풀이 (알파벳, DFS)  (0) 2021.07.17
백준 2206 파이썬 풀이 (BFS, 벽 부수고 이동하기, 이차 배열 사용)  (0) 2021.07.12
백준 7562 python 풀이 (나이트의 이동, BFS, 그래프)  (0) 2021.07.10
백준 7569 토마토 (BFS, 3차원)  (0) 2021.07.09
백준 1697 숨바꼭질 (BFS)  (0) 2021.05.18
    '알고리즘' 카테고리의 다른 글
    • 백준 1987 파이썬 풀이 (알파벳, DFS)
    • 백준 2206 파이썬 풀이 (BFS, 벽 부수고 이동하기, 이차 배열 사용)
    • 백준 7562 python 풀이 (나이트의 이동, BFS, 그래프)
    • 백준 7569 토마토 (BFS, 3차원)
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin

    티스토리툴바