𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[μ•Œκ³ λ¦¬μ¦˜] κ·Έλž˜ν”„ 순회 문제 - 1. 깊이 μš°μ„  탐색(DFS) λ³Έλ¬Έ

μ•Œκ³ λ¦¬μ¦˜

[μ•Œκ³ λ¦¬μ¦˜] κ·Έλž˜ν”„ 순회 문제 - 1. 깊이 μš°μ„  탐색(DFS)

.23 2021. 7. 21. 02:37

'μ½”λ”© ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•œ 자료 ꡬ쑰와 μ•Œκ³ λ¦¬μ¦˜ with C++' λ₯Ό μ°Έκ³ ν•˜μ—¬ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

> κ·Έλž˜ν”„ κ°œλ… 더보기

1. κ·Έλž˜ν”„ ; Graph

1.1 κ°œλ…

κ·Έλž˜ν”„ 순회 문제λ₯Ό λ“€μ–΄κ°€κΈ° μ „ 짧게 κ·Έλž˜ν”„μ— λŒ€ν•΄ μ„€λͺ…ν•˜μžλ©΄, κ·Έλž˜ν”„λŠ” 정점(vertex)의 집합과 정점듀을 μ„œλ‘œ μž‡λŠ” κ°„μ„ (edge)의 μ§‘ν•©μœΌλ‘œ κ΅¬μ„±λœ 자료ꡬ쑰둜 μ—°κ²°λ˜μ–΄ μžˆλŠ” 객체 κ°„μ˜ 관계λ₯Ό ν‘œν˜„ν•  수 μžˆλ‹€. μˆ˜ν•™μ μœΌλ‘œλŠ” G = <V, E>(vλŠ” 정점, eλŠ” κ°„μ„ μ˜ 집합) ν˜•νƒœλ‘œ ν‘œν˜„ν•  수 μžˆλ‹€. κ°„μ„  λ°©ν–₯의 μœ λ¬΄μ— 따라 λ°©ν–₯ κ·Έλž˜ν”„(directed graph)와 무방ν–₯ κ·Έλž˜ν”„(undirected graph)둜 λ‚˜λˆŒ 수 있고, κ°„μ„ μ˜ κ°€μ€‘μΉ˜ μœ λ¬΄μ— 따라 가쀑 κ·Έλž˜ν”„(weighted graph)와 비가쀑 κ·Έλž˜ν”„(unweighted graph)둜 λ‚˜λˆˆλ‹€.

2. κ·Έλž˜ν”„ 순회 문제 ; Graph Traversal Problem

2.1 κ°œλ…

κ·Έλž˜ν”„ 순회 λ¬Έμ œλŠ” κ·Έλž˜ν”„μ˜ ν•œ μ •μ μ—μ„œ μ‹œμž‘ν•˜μ—¬ 남은 λͺ¨λ“  정점을 λ°©λ¬Έν•˜λŠ” 문제λ₯Ό μ˜λ―Έν•œλ‹€. λ˜ν•œ νŠΉμ •ν•œ 정점을 μ°ΎκΈ° μœ„ν•΄ μ‚¬μš©λ  수 있기 λ•Œλ¬Έμ— κ·Έλž˜ν”„ 탐색 문제(graph search problem)라고도 ν•œλ‹€. 각각 정해진 μˆœμ„œλ‘œ λͺ¨λ“  정점을 λ°©λ¬Έν•˜λŠ” μ—¬λŸ¬ κ·Έλž˜ν”„ 탐색 μ•Œκ³ λ¦¬μ¦˜λ“€μ΄ μžˆλŠ”λ°, κ·Έ 쀑 κ°€μž₯ 잘 μ•Œλ €μ§„ μ•Œκ³ λ¦¬μ¦˜μ—λŠ” λ‹€μŒ 두 κ°œκ°€ μžˆλ‹€.

 

1. 깊이 μš°μ„  탐색(Depth-First Search)

2. λ„ˆλΉ„ μš°μ„  탐색(Breadth-First Search)

 

2.2 κ·Έλž˜ν”„ 순회 μ•Œκ³ λ¦¬μ¦˜

2.2.1 깊이 μš°μ„  탐색 ; Depth-First Search

깊이 μš°μ„  탐색(DFS)은 μ‹œμž‘ μ •μ μ—μ„œλΆ€ν„° νŠΉμ • 경둜λ₯Ό 따라 κ°€λŠ₯ν•œ 멀리 μžˆλŠ” 정점을 μž¬κ·€μ μœΌλ‘œ λ¨Όμ € λ°©λ¬Έν•˜λŠ” 방식을 μ˜λ―Έν•œλ‹€. 더 λ°©λ¬Έν•  정점이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ λ‹€μ‹œ λ’€λ‘œ λŒμ•„κ°€ λ‹€λ₯Έ 경둜λ₯Ό μ°Ύμ•„κ°„λ‹€.

κ·Έλž˜ν”„ μ˜ˆμ‹œ

λ‹€μŒκ³Ό 같은 λͺ¨μ–‘μ˜ κ·Έλž˜ν”„κ°€ μžˆλ‹€κ³  κ°€μ •ν•œλ‹€. 0번째 정점을 μ‹œμž‘μœΌλ‘œ μž‘μ€ κ°’λΆ€ν„° μ°Ύμ•„κ°„λ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ, DFS μ•Œκ³ λ¦¬μ¦˜μ„ μ μš©ν•˜λ©΄ λ‹€μŒκ³Ό 같은 μˆœμ„œλ‘œ μ§„ν–‰λœλ‹€.

1단계 : 0번 정점 λ°©λ¬Έ

2단계 : 0번 정점과 μΈμ ‘ν•œ 정점 쀑 κ°€μž₯ 값이 μž‘μ€ 1번 정점 λ°©λ¬Έ

3단계 : 1번 정점과 μΈμ ‘ν–ˆκ³ , 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 정점 쀑 κ°€μž₯ 값이 μž‘μ€ 2번 정점 λ°©λ¬Έ

4단계 : 2번 정점과 μΈμ ‘ν–ˆκ³ , 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 정점 쀑 κ°€μž₯ 값이 μž‘μ€ 3번 정점 λ°©λ¬Έ

5단계 : 3번 정점과 μΈμ ‘ν–ˆκ³ , 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 정점 쀑 κ°€μž₯ 값이 μž‘μ€ 4번 정점 λ°©λ¬Έ

6단계 : 4번 정점과 μΈμ ‘ν–ˆκ³ , 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 정점인 6번 정점 λ°©λ¬Έ

7단계 : 6번 정점과 μΈμ ‘ν–ˆκ³ , 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 정점인 5번 정점 λ°©λ¬Έ. 이후 더 이상 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 정점이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ DFS μ’…λ£Œ.

λ”°λΌμ„œ μœ„μ˜ κ·Έλž˜ν”„λ₯Ό DFSλ₯Ό 톡해 μˆœνšŒν•˜μ˜€μ„ λ•Œ 0 ➑️ 1 ➑️ 2 ➑️ 3 ➑️ 4 ➑️6 ➑️ 5 μˆœμ„œλ‘œ λ°©λ¬Έν•œλ‹€.

 

2.2.2 깊이 μš°μ„  탐색 μ½”λ“œ

깊이 μš°μ„  탐색을 κ΅¬ν˜„ν•˜λŠ” 데 μŠ€νƒμ„ μ‚¬μš©ν•˜κΈ°λ„ ν•˜κ³  μž¬κ·€ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜κΈ°λ„ ν•˜λŠ”λ°, μž¬κ·€ 호좜 방식을 μ„ νƒν•˜μ˜€λ‹€. 정점과 κ°„μ„  정보가 λ‹΄κΈ΄ 1차원 μ •μˆ˜ λ°°μ—΄ 벑터 graph와 λ°©λ¬Έ μ—¬λΆ€λ₯Ό ν‘œμ‹œν•˜λŠ” bool 벑터 visitedλ₯Ό μ΄μš©ν•˜μ—¬, λ°©λ¬Έν•  정점을 μ„ νƒν•œ λ’€ DFSλ₯Ό μ‹€ν–‰ν•œλ‹€. μ‹œκ°„ λ³΅μž‘λ„λŠ” O(V + E) (V : μ •μ μ˜ 개수, E : κ°„μ„ μ˜ 개수)둜 BFS와 λ™μΌν•˜λ‹€.

μ‹œμž‘μ μœΌλ‘œλΆ€ν„° νŠΉμ • 경둜λ₯Ό 따라 μ΄λ™ν•˜κΈ° λ•Œλ¬Έμ— 멀리 λ–¨μ–΄μ Έ μžˆλŠ” 정점을 찾을 λ•Œ μ ν•©ν•˜λ‹€.

void DFS(int vertex) {
    visited[vertex] = true;
    printf("%d ", vertex); // λ°©λ¬Έ 정점 좜λ ₯
    for(int i = 0; i < graph[vertex].size(); i++) {
        int next = graph[vertex][i];
        if(!visited[next])
            DFS(next);
    }
}

 

μœ„μ˜ ν•¨μˆ˜λ₯Ό μ΄μš©ν•œ 전체 μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€. 정점과 κ°„μ„  μž…λ ₯ 방식은 λ°±μ€€ 1260번 DFS와 BFSλ₯Ό μ΄μš©ν•˜μ˜€λ‹€.

> 전체 μ½”λ“œ 보기
#include <cstdio>
#include <vector>
#define MAX 1001

using namespace std;

vector<int> graph[MAX];
vector<bool> visited(MAX, false);

void DFS(int vertex);

int main(void) {
    int v, e, start;
    scanf("%d %d %d", &v, &e, &start);

    visited.resize(e + 1);
    
    for(int i = 0; i < e; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    DFS(start);
    
    return 0;
}

void DFS(int vertex) {
    visited[vertex] = true;
    printf("%d ", vertex);
    for(int i = 0; i < graph[vertex].size(); i++) {
        int next = graph[vertex][i];
        if(!visited[next])
            DFS(next);
    }
}​
Comments