Dev/Algorithm

[백준] 그래프의 탐색 (DFS, BFS)

VIPeveloper 2021. 3. 27. 20:49
728x90
반응형

그래프의 탐색에는 깊이우선 탐색과, 너비우선 탐색 방법 두가지 방법이 존재한다.

각각을 구할 때, 인접행렬로 구하는 방식이 있고, 간선 리스트로 구하는 방식이 존재한다.

인접행렬은 이차원배열이기 때문에 O(N^2)의 시간이 걸리고, 간선리스트는 간선의 합만큼만 시간복잡도가 걸리기 때문에 O(V+E) 의 시간복잡도가 존재한다.

시간을 최소화 하고싶다면 간선리스트로 구현하자!

 

1260번. DFS와 BFS

https://www.acmicpc.net/problem/1260
더보기
def dfs(n,v):
    global arr,check
    check[v] = True
    print(v,end=' ')
    for i in range(1,n+1):
        if arr[v][i] == 1 and check[i] == False:
            dfs(n,i)


def bfs(n,v):
    global arr
    check = [False] * (n+1)
    q = []
    q.append(v)
    check[v] = True
    while len(q) != 0:
        x = q.pop(0)
        print(x,end=' ')
        for i in range(1,n+1):
            if arr[x][i] == 1 and check[i] == False:
                check[i] = True
                q.append(i)



n,m,v = list(map(int,input().split()))
arr = [[0] * (n+1) for _ in range(n+1)]
check = [False] * (n+1)
for _ in range(m):
    a,b = list(map(int,input().split()))
    arr[a][b] = 1
    arr[b][a] = 1
dfs(n,v)
print()
bfs(n,v)

간선리스트로도 한번 구현해보았다.

더보기
def dfs(n,v):
    global arr,check
    check[v] = True
    print(v,end=' ')
    for i in arr[v]:
        if check[i] == False:
            dfs(n,i)

def bfs(n,v):
    global arr
    check = [False] * (n+1)
    q = []
    q.append(v)
    check[v] = True
    while q:
        x = q.pop(0)
        print(x,end=' ')
        for i in arr[x]:
            if check[i] == False:
                check[i] = True
                q.append(i)



n,m,v = list(map(int,input().split()))
arr = [[] for _ in range(n+1)]
check = [False] * (n+1)
for _ in range(m):
    a,b = list(map(int,input().split()))
    arr[a].append(b)
    arr[b].append(a)
for i in range(n+1):
    arr[i].sort()
dfs(n,v)
print()
bfs(n,v)

간선리스트 vs 인접리스트

메모리, 시간에서 차이를 보였다. 경우의 수가 더 많다면 더 큰 차이를 보이지 않을까 생각한다. 메모리면에서도 2차원 배열을 다 사용하는 것과, 정확한 메모리 공간을 차지하는 것의 차이점이 있다는 것을 알 수 있었다.

 

11724번. 연결 요소의 개수

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

파이썬으로 아무리 해도 시간초과가 발생하는 문제. 덕분에 현타와서 몇일 알고리즘을 쉬었다. 

input().split() vs sys.stdin.readline().split() 으로 시간초과 여부가 갈리게 되는 것을 확인하였다.

더보기
import sys
sys.setrecursionlimit(10000)


def solution(start):
    global arr,check
    check[start] = True
    for i in arr[start]:
        if check[i] == False:
            solution(i)


n,m = map(int,sys.stdin.readline().split())
arr = [[] for _ in range(n+1)]
check = [False] * (n+1)
for _ in range(m):
    a,b = map(int,sys.stdin.readline().split())
    arr[a].append(b)
    arr[b].append(a)
for i in range(n):
    arr[i].sort()
answer = 0
for i in range(1,n+1):
    if check[i] == False:
        solution(i)
        answer += 1
print(answer)

1707번. 이분 그래프

https://www.acmicpc.net/problem/1707
더보기
import sys
sys.setrecursionlimit(10 ** 6)


def solution(start,color):
    global arr,check
    check[start] = color
    for i in arr[start]:
        if check[i] == 0:
            if solution(i,3-color) == False:
                return False
        elif check[i] == check[start]:
            return False
    return True


case = int(input())
for _ in range(case):
    n,m = map(int,sys.stdin.readline().split())
    arr = [[] for _ in range(n+1)]
    check = [0] * (n+1)
    for _ in range(m):
        a,b = map(int,sys.stdin.readline().split())
        arr[a].append(b)
        arr[b].append(a)
    for i in range(n):
        arr[i].sort()
    ans = True
    for i in range(1,n+1):
        if check[i] == 0:
            ans = solution(i,1)
            if ans == False:
                break
    print("YES" if ans else "NO")
728x90
반응형

'Dev > Algorithm' 카테고리의 다른 글

12. [알고리즘] K번째 약수  (0) 2021.04.29
[백준] 플러드필  (0) 2021.04.01
[백준] 그래프와 BFS  (0) 2021.03.22
[백준] 재귀함수 사용하기  (0) 2021.03.15
[백준] 순열 (Permutation)  (0) 2021.03.12