πŸ“ Coding Test Study

[Algorithm&자료ꡬ쑰] BFS/DFS?

ibelieveinme 2021. 4. 13. 04:22
728x90

β˜… BFS/DFS νƒμƒ‰μ˜ λͺ©μ 

: μ‹œμž‘μ  Xμ—μ„œ μ‹œμž‘ν•΄μ„œ λͺ¨λ“  정점을 ν•œ λ²ˆμ”© λ°©λ¬Έν•˜λŠ” 것.

 

1. DFS(깊이 μš°μ„  탐색) Stack(ν›„μž…μ„ μΆœ) κ³Ό μž¬κ·€ν•¨μˆ˜ μ‚¬μš©

: ν•œ μ‹œμž‘μ μ—μ„œ 갈 수 μžˆμ„ λ•ŒκΉŒμ§€ κ³„μ†ν•΄μ„œ μ§„ν–‰. 더 이상 μ§„ν–‰ν•  수 없을 λ•Œ μ΄μ „μœΌλ‘œ λŒμ•„μ™€μ„œ λ‹€μ‹œ 갈 수 μžˆμ„ λ•ŒκΉŒμ§€ μ§„ν–‰

: λ°©λ¬Έν–ˆλŠ” μ§€, μ•ˆν–ˆλŠ” μ§€λ₯Ό 체크할 visited[] λ°°μ—΄ μ‚¬μš©

i 1 2 3 4 5 6
visited[i] 0 0 0 0 0 0

1) 1 λ°©λ¬Έ

    stack 1

    visited[1] = 1 λŒ€μž…

2) 1κ³Ό μ—°κ²°λœ 2, 5 쀑에 μž‘μ€ 값인 2 λ°©λ¬Έ(정점 값이 μž‘μ€ 곳으둜 이동)

    stack 1 2

    visited[2] = 1

3) 2와 μ—°κ²°λœ 3, 5 쀑에 3 λ°©λ¬Έ

    stack 1 2 3

    visited[3] = 1

3) 3κ³Ό μ—°κ²°λœ 4 λ°©λ¬Έ

    stack 1 2 3 4

    visited[4] = 1

4) 4와 μ—°κ²°λœ 5, 6 쀑에 5 λ°©λ¬Έ

    stack 1 2 3 4 5

    visited[5] = 1

5) 5μ—μ„œ 더이상 갈 수 μžˆλŠ” 곳이 μ—†μœΌλ―€λ‘œ stack의 λ§ˆμ§€λ§‰(λ°”λ‘œ μ „ μ „ 정점) κ°’(4)으둜 λŒμ•„κ°€κΈ°.

    stack 1 2 3 4

6) 4μ—μ„œ λ‹€μ‹œ 탐색을 μ‹œμž‘ν•˜μ—¬ 6 λ°©λ¬Έ

    stack 1 2 3 4 6

    visited[6] = 1

7) 2μ—μ„œ 더이상 갈 수 μžˆλŠ” κ³³(visited[i] = 0 인 κ³³)이 μ—†μœΌλ―€λ‘œ stackμ—μ„œ ν•˜λ‚˜μ”© κΊΌλ‚΄μ„œ 1둜 λŒμ•„μ˜€κΈ°

    stack 

 

1) DFSλ₯Ό 인접 ν–‰λ ¬λ‘œ κ΅¬ν˜„ν•˜λŠ” 방법 -> μ‹œκ°„λ³΅μž‘λ„ O(V^2)

void dfs(int x){
	visited[x] = true;
	cout << x;
	for(int i = 1; i<=n; i++){
		if(a[x][i] == 1 && visited[i] == false){
			dfs(i);
		}
	}
}

; λͺ¨λ“ μ •점을 탐색

 

2) DFSλ₯Ό 인접 리슀트둜 κ΅¬ν˜„ν•˜λŠ” 방법 -> μ‹œκ°„ λ³΅μž‘λ„ O(V+E)

void dfs(int x){
	visited[x] = true;
    cout << x;
    for(int i = 0; i<a[x].size(); i++){
    	int y = a[x][i];
        if(visited[y] == false){
        	dfs(y);
            }
        }
    }
}

; 인접행렬과 λ‹€λ₯Έ 점은 a[x]에 μ €μž₯된 μ—°κ²°λœ λ‹€μŒ κ°„μ„ λ§Œμ„ μ°Ύμ•„μ„œ 탐색할 수 있음.

 

 

2. BFS(λ„ˆλΉ„ μš°μ„  탐색) queue(μ„ μž…μ„ μΆœ) 이용

: ν•œ μ‹œμž‘μ μ—μ„œ 갈 수 μžˆλŠ” 경우λ₯Ό λͺ¨λ‘ νƒμƒ‰ν•˜λ©΄μ„œ μ§„ν–‰.

: 큐λ₯Ό μ΄μš©ν•΄μ„œ μ§€κΈˆ μœ„μΉ˜μ—μ„œ 갈 수 μžˆλŠ” 것을 λͺ¨λ‘ 큐에 λ„£λŠ” 방식.

: νμ— 넣을 λ•Œ λ°©λ¬Έν–ˆλ‹€κ³  체크해야 ν•œλ‹€. visited[] λ°°μ—΄ μ‚¬μš©

i 1 2 3 4 5 6
visited[i] 0 0 0 0 0 0

1) queue 1 λ„£κ³  visited 체크

  visited[1] = 1

2) queue.pop() ν•΄μ„œ queue의 첫번째 값인 1λΆ€ν„° 탐색 μ‹œμž‘

  queue 

2) 1κ³Ό μ—°κ²°λœ 2, 5 큐에 μ €μž₯ν•˜κ³  visited 체크

   queue 2 5

   visited[2] = 1, visited[5] = 1

2) queue.pop() ν•΄μ„œ queue의 맨 μ•ž 값인 2 λΆ€ν„° 탐색 μ‹œμž‘

   queue 5

3) 2와 μ—°κ²°λœ 3 queue에 μ €μž₯ν•˜κ³  visited 체크

   queue 5 3

   visited[3] = 1

4) queue.pop()ν•΄μ„œ queue의 맨 μ•ž 값인 5 λΆ€ν„° 탐색 μ‹œμž‘

   queue 3

5) 5와 μ—°κ²°λœ 4 queue에 μ €μž₯ν•˜κ³  visited 체크

   queue 3 4

   visited[4] = 1

6) queue.pop()ν•΄μ„œ queue의 맨 μ•ž 값인 3 λΆ€ν„° 탐색 μ‹œμž‘

   queue 4

7) 3κ³Ό μ—°κ²°λœ 정점 쀑에 탐색할 수 μžˆλŠ” 정점이 μ—†μœΌλ―€λ‘œ λ‹€μ‹œ queue.pop() ν•΄μ„œ 4μ—μ„œ 탐색 μ‹œμž‘

   queue 

8) 4와 μ—°κ²°λœ 6 queue에 μ €μž₯ν•˜κ³  visited 체크

   queue 6

   visited[6] = 1

9) queue.pop()ν•΄μ„œ queue의 맨 μ•ž 값인 6 μ—μ„œ 탐색 μ‹œμž‘

   queue

10) 6κ³Ό μ—°κ²°λœ 정점 쀑에 λ°©λ¬Έν•  정점없고, queue κ°€ λΉ„μ—ˆμœΌλ―€λ‘œ 탐색 μ’…λ£Œ.

 

1) BFSλ₯Ό 인접 ν–‰λ ¬λ‘œ κ΅¬ν˜„ν•˜λŠ” 방법 -> μ‹œκ°„λ³΅μž‘도 O(V^2)

queue<int> q;
visited[1] = true;
q.push(1);
while(!q.empty()){
	int x = q.front();
    q.pop();
    cout << x;
    for(int i = 1; i<=n; i=+){
    	if(a[x][i] == 1 && visited[i] == false){
        	visited[i] = true;
            q.push(i);
           }
     }
}

2) BFSλ₯Ό 인접 ν–‰λ ¬λ‘œ κ΅¬ν˜„ν•˜λŠ” 방법 -> μ‹œκ°„ λ³΅μž‘λ„ O(V+E)

queue<int> q;
visited[1] = true;
q.push(1);
while(!q.empty()){
	int x = q.front();
    q.pop();
    cout << x;
    for(int i = 1; i<a[x].size(); i=+){
    int y = a[x][i];
    	if(visited[y] == false){
        	visited[y] = true;
            q.push(y);
           }
     }
}

 

<참고문제>

 

1260번: DFS와 BFS

첫째 쀄에 μ •μ μ˜ 개수 N(1 ≤ N ≤ 1,000), κ°„μ„ μ˜ 개수 M(1 ≤ M ≤ 10,000), 탐색을 μ‹œμž‘ν•  μ •μ μ˜ 번호 Vκ°€ μ£Όμ–΄μ§„λ‹€. λ‹€μŒ M개의 μ€„μ—λŠ” 간선이 μ—°κ²°ν•˜λŠ” 두 μ •μ μ˜ λ²ˆν˜Έκ°€ μ£Όμ–΄μ§„λ‹€. μ–΄λ–€ 두 정점 사

www.acmicpc.net

 

728x90