๐ค DFS ( Depth First Search ) ๊น์ด ์ฐ์ ํ์?
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ํ๋์ ์ ์ ์ผ๋ก๋ถํฐ ์์ํ์ฌ ์ฐจ๋ก๋๋ก ๋ชจ๋ ์ ์ ๋ค์ ํ ๋ฒ์ฉ ๋ฐฉ๋ฌธํ๋ ์๊ณ ๋ฆฌ์ฆ ์ ๋๋ค.
์ฆ ๊ทธ๋ํ ํํ์ ์๋ฃ๊ตฌ์กฐ์์ ๋ฃจํธ ๋ ธ๋์์ ์์ํด์ ๋ค์ ๋ถ๊ธฐ๋ก ๋์ด๊ฐ๊ธฐ ์ ์ ํด๋น ๋ถ๊ธฐ๋ฅผ ์๋ฒฝํ๊ฒ ํ์ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
๊ทธ๋ฆผ์ฒ๋ผ ํ ๋ฐฉํฅ์ผ๋ก ์ธ์ ํ ๋ ธ๋๊ฐ ์์ ๋๊น์ง ํ์ํ ํ ์ด์ ๋ ธ๋๋ก ๋์๊ฐ์ ๋ค์ ์ธ์ ํ ๋ ธ๋๋ฅผ ํ์ํ๋ฉฐ ์ด ๊ณผ์ ์ ๋ฐ๋ณตํฉ๋๋ค.
์ฅ์
- ํ์ฌ ๊ฒฝ๋ก์์ ๋ ธ๋๋ฅผ ๊ธฐ์ตํ๊ธฐ ๋๋ฌธ์ ์ ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ์ฐพ์ผ๋ ค๋ ๋ ธ๋๊ฐ ๊น์ ๋จ๊ณ์ ์๋ ๊ฒฝ์ฐ BFS๋ณด๋ค ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์์ต๋๋ค.
๋จ์
- DFS๋ฅผ ํตํด ์ป์ด์ง ํด๊ฐ ์ต๋จ ๊ฒฝ๋ก๋ผ๋ ๋ณด์ฅ์ด ์์ต๋๋ค. DFS๋ ์ฐพ์ผ๋ ค๋ ํด์ ๋์ฐฉํ๋ฉด ํ์์ ์ข ๋ฃํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ์ต์ ์ ๊ฒฝ์ฐ, ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ํ์ํจ์ผ๋ก ํด์ ๋๋ฌํ๋ ๋ฐ ๊ฐ์ฅ ์ค๋ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์๋ค.
โ ๋ฌธ์ ์ ํ
- ๊ฒฝ๋กํ์ ์ ํ ( ์ต๋จ๊ฑฐ๋ฆฌ, ์๊ฐ )
- ๋คํธ์ํฌ ์ ํ ( ์ฐ๊ฒฐ )
- ์กฐํฉ ์ ํ (๋ชจ๋ ์กฐํฉ ๋ง๋ค๊ธฐ )
โ ์๊ฐ ๋ณต์ก๋
DFS๋ฅผ ์ฌ์ฉํ ๋ ๊ทธ๋ํ๋ฅผ ์ธ์ ํ๋ ฌ ๋๋ ์ธ์ ๋ฆฌ์คํธ ๋ก ํํํ ๊ฒฝ์ฐ์ ๋ฌ๋ผ์ง๋๋ค.
์ธ์ ํ๋ ฌ์ ์ด์ฐจ์ ๋ฐฐ์ด์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ทธ๋ํ์ Vertex์ ์ ๋งํผ ์ด์ฐจ์ ๋ฐฐ์ด์ ์์ฑํฉ๋๋ค.
DFS์ ํน์ฑ์ ํด๊ฐ ์ ํด์ ธ์์ง ์์ผ๋ฉด ๋ชจ๋ ๋ ธ๋๋ฅผ ํ์ํด์ผ ํฉ๋๋ค.
์ด์ฐจ์ ๋ฐฐ์ด์ ๋ชจ๋ ๋ฐฉ์ ํ์ํ๋ค๋ฉด Vertex * Vertex ์ฆ, O( N^2)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค
์ธ์ ๋ฆฌ์คํธ๋ LinkedList๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฐ Vertex(๋ ธ๋)์์ ์ฐ๊ฒฐ์ (Edge)์ผ๋ก ์ฐ๊ฒฐ๋ Vertex๊น์ง ํ์ํ๋ฉฐ ๊ฐ Vertex์ Edge์ ์๋งํผ ํ์ํ๊ฒ ๋ฉ๋๋ค. ์ฆ, Vertex + Edge๋ฅผ ๋ํ ๋งํผ O( Vertex + Edge )์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค.
โ ํ์ ๋ฐฉ๋ฒ
ํ์์ Stack ๋๋ ์ฌ๊ทํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ ์ ์์ต๋๋ค.
๋ฐฑ์ค 2667๋ฒ์ ์์ ๋ก DFS๋ฅผ ์ฌ์ฉํด ๋ณด๊ฒ ์ต๋๋ค.
https://www.acmicpc.net/problem/2667
๊ทธ๋ฆผ์ฒ๋ผ ํ๋ ฌ์์ ์ธ์ ํ ์ง( 1 )์ ์์ ๊ฐ ์ง์ด ๋ชจ์ฌ์๋ ๋จ์ง์ ์๋ฅผ ์ฐพ๋ ๋ฌธ์ ์ ๋๋ค.
๐ ์ฌ๊ทํจ์ ์ฌ์ฉ
์กฐ๊ฑด์ ๋ง๋ ์ธ์ ํ ๋ ธ๋๋ฅผ ๋ค์ ํจ์๋ฅผ ํธ์ถํ์ฌ ํ์ํฉ๋๋ค.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.StringBuilder;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
public class Main{
static List<Integer> result;
static boolean[][] chk;
static int[][] map;
static int cnt, n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
n = Integer.parseInt(br.readLine());
map = new int[n][n];
chk = new boolean[n][n];
result = new ArrayList<>();
cnt = 1;
// ์
๋ ฅ๋ฐ์ ์ง๋(ํ์ด)๋ฅผ ํ์ํ๊ธฐ์ํด ์ด์ฐจ์๋ฐฐ์ด์ ์ถ๊ฐํด์ค๋๋ค.
for( int i = 0; i<n; i++){
String[] arr = br.readLine().split("");
for( int j = 0; j<n; j++){
map[i][j] = Integer.parseInt(arr[j]);
}
}
for( int i = 0; i<n; i++){
for( int j = 0; j<n; j++){
if( map[i][j] == 1 && !chk[i][j] ){ // 1์ด๊ณ ์ฒดํฌํ์ง ์์ ์ฆ, ํ์ํ์ง ์์ ์ง
dfs(i, j); // dfs ํธ์ถ
result.add(cnt); // dfs๋ฅผ ํตํด ์ธ์ ํ ์ง ์ ์ถ๊ฐ
cnt = 1; // cnt ์ด๊ธฐํ
}
}
}
Collections.sort(result); // ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
sb.append(result.size()).append("\n");
for( int i : result ){
sb.append(i).append("\n");
}
System.out.print(sb);
}
static void dfs(int y, int x){
chk[y][x] = true;
int[] dy = {0,1,0,-1};
int[] dx = {1,0,-1,0};
for( int i = 0; i<4; i++){ // 4๋ฐฉํฅ์ ๋
ธ๋๋ฅผ ๋ชจ๋ ํ์
int ny = y + dy[i];
int nx = x + dx[i];
if( ny >= 0 && nx >= 0 && ny < n && nx < n ){ //์ธ์ ํ ๋
ธ๋๊ฐ ์๋ค๋ฉด ํ์ํ์ง ์์ต๋๋ค.
if( map[ny][nx] == 1 && chk[ny][nx] == false){
cnt++;
dfs(ny, nx); // dfs์ฌ๊ท ํธ์ถ
}
}
}
}
}
๐ Stack ์ฌ์ฉ
์กฐ๊ฑด์ ๋ง๋ ์ธ์ ํ ๋ ธ๋๋ค์ stack์ ๋ชจ๋ ๋ด๊ณ ํ๋์ฉ ์ ๊ฑฐํ๋ฉด์ ํ์์ ์ํํฉ๋๋ค.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.StringBuilder;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Stack;
public class Main{
static List<Integer> result;
static boolean[][] chk;
static int[][] map;
static int cnt, n;
static Stack<int[]> stack;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
n = Integer.parseInt(br.readLine());
map = new int[n][n];
chk = new boolean[n][n];
result = new ArrayList<>();
stack = new Stack<>();
cnt = 1;
// ์
๋ ฅ๋ฐ์ ์ง๋(ํ์ด)๋ฅผ ํ์ํ๊ธฐ์ํด ์ด์ฐจ์๋ฐฐ์ด์ ์ถ๊ฐํด์ค๋๋ค.
for( int i = 0; i<n; i++){
String[] arr = br.readLine().split("");
for( int j = 0; j<n; j++){
map[i][j] = Integer.parseInt(arr[j]);
}
}
for( int i = 0; i<n; i++){
for( int j = 0; j<n; j++){
if( map[i][j] == 1 && !chk[i][j]){
dfsUseStack(i, j);
result.add(cnt);
cnt=1;
}
}
}
Collections.sort(result); // ์ค๋ฆ์ฐจ์ ์ ๋ ฌ
sb.append(result.size()).append("\n");
for( int i : result ){
sb.append(i).append("\n");
}
System.out.print(sb);
}
static void dfsUseStack(int y, int x){
chk[y][x] = true;
stack.push(new int[]{y, x});
int[] dy = {0,1,0,-1};
int[] dx = {1,0,-1,0};
while (!stack.isEmpty()){
int[] arr = stack.pop();
for( int i = 0; i<4; i++){
int ny = arr[0] + dy[i];
int nx = arr[1] + dx[i];
if( ny >= 0 && nx >= 0 && ny < n && nx < n ){ //ํ์ง๋ง ์ ๋
ธ๋๊ฐ ์๋ค๋ฉด ํ์ํ์ง ์๋๋ก ์กฐ๊ฑด
if( map[ny][nx] == 1 && chk[ny][nx] == false){
cnt++;
chk[ny][nx] = true;
stack.push(new int[]{ny, nx}); //์กฐ๊ฑด์ ๋ง๋ ์ธ์ ๋
ธ๋๋ฅผ stack์ ์ถ๊ฐํฉ๋๋ค.
}
}
}
}
}
}
๐ Reference :