めけゃくけゃ ι–‹η™Ίθ€…πŸ¦Ύ
μ½”λ”© 짐 πŸ’ͺ
めけゃくけゃ ι–‹η™Ίθ€…πŸ¦Ύ
  • μΉ΄ν…Œκ³ λ¦¬ (135)
    • 개발 ν™˜κ²½ ꡬ좕 (12)
      • 개발 ν™˜κ²½ (5)
      • DB (0)
      • Node.js (4)
      • ν˜•μƒ 관리 (2)
      • Spring (1)
    • μ›Ή (11)
      • React (5)
      • 슀파λ₯΄νƒ€μ½”λ”©ν΄λŸ½__μ›Ή (6)
    • λͺ¨λ°”일 (2)
      • μ•ˆλ“œλ‘œμ΄λ“œ (2)
    • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ (55)
      • C (13)
      • Python (15)
      • SQL (5)
      • Java (22)
    • 사물인터넷 (11)
      • 아두이노 (11)
    • 일상 (31)
      • λ§›μ§‘ (13)
      • λž­ν‚Ήλ‹­μ»΄ (4)
      • ν›„κΈ° (11)
      • μš”λ¦¬ (3)
      • μž‘λ‹΄ (0)
    • ꡐ양 (4)
      • 심리학 (3)
      • ν…Œλ‹ˆμŠ€ (1)
    • 자격증 (9)
      • μ •λ³΄μ²˜λ¦¬κΈ°μ‚¬ (9)

λΈ”λ‘œκ·Έ 메뉴

  • πŸ’» github

인기 κΈ€

졜근 κΈ€

ν‹°μŠ€ν† λ¦¬

hELLO Β· Designed By μ •μƒμš°.
めけゃくけゃ ι–‹η™Ίθ€…πŸ¦Ύ

μ½”λ”© 짐 πŸ’ͺ

[자료ꡬ쑰] κ·Έλž˜ν”„ 탐색 (DFS, BFS)
ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄/C

[자료ꡬ쑰] κ·Έλž˜ν”„ 탐색 (DFS, BFS)

2022. 7. 4. 00:31

[ κ·Έλž˜ν”„μ˜ 탐색 ] 

더보기

- κ·Έλž˜ν”„μ˜ 탐색

  β”” ν•˜λ‚˜μ˜ μ •μ μœΌλ‘œλΆ€ν„° μ‹œμž‘ν•˜μ—¬ μ°¨λ‘€λŒ€λ‘œ λͺ¨λ“  정점듀을 ν•œλ²ˆμ”© λ°©λ¬Έν•˜μ—¬ νƒμƒ‰ν•˜λŠ” 것

        λ§Žμ€ λ¬Έμ œλ“€μ΄ λ‹¨μˆœ κ·Έλž˜ν”„μ˜ λ…Έλ“œ(정점)λ₯Ό νƒμƒ‰ν•˜λŠ κ²ƒμœΌλ‘œ ν•΄κ²° κ°€λŠ₯함

 

- 탐색 방법

  β”” 깊이 μš°μ„  탐색 ( DFS : Depth First Search )

        λ„ˆλΉ„ μš°μ„  탐색 ( BFS : Breath First Search )

(쒌) DFS : 0-1-3-4-2-5-6  (우) BFS : 0-1-2-3-4-5-6

 

DFS BFS 탐색 비ꡐ

 

 

[ 깊이 μš°μ„  탐색 (DFS) ]

더보기

- 깊이 μš°μ„  탐색 (DFS)

  β”” νŠΈλ¦¬λ‚˜ κ·Έλž˜ν”„μ—μ„œ ν•œ 루트둜 νƒμƒ‰ν•˜λ‹€κ°€ νŠΉμ • μƒν™©μ—μ„œ μ΅œλŒ€ν•œ 깊이 λ“€μ–΄κ°€μ„œ ν™•μΈν•œ λ’€ λ‹€μ‹œ λŒμ•„κ°€ λ‹€λ₯Έ 루트둜 νƒμƒ‰ν•˜λŠ” 탐색 방법이닀.

        주둜 μŠ€νƒμ„ μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„, λ‹¨μˆœ 탐색 속도 μžμ²΄λŠ” λ„ˆλΉ„ μš°μ„  탐색 (BFS)에 λΉ„ν•΄ 느림.

        탐색이 μ•„λ‹Œ 순회λ₯Ό ν•  경우 자주 μ‚¬μš©ν•œλ‹€

        β‘  갈림길이 λ‚˜νƒ€λ‚  λ•Œλ§ˆλ‹€ 'λ‹€λ₯Έ κΈΈ'의 μ •λ³΄λ§Œ κΈ°λ‘ν•˜λ©° μ§€λ‚˜μ˜¨ 길을 μ§€μš΄λ‹€

        β‘‘ 더 이상 갈 수 μ—†κ²Œ 되면 μ§μ „μ˜ κ°ˆλ¦ΌκΈΈκΉŒμ§€ λŒμ•„κ°€λ©° ν˜„μž¬ λ£¨νŠΈλŠ” μ•„λ‹ˆλΌλŠ” ν‘œμ‹μ„ 남긴닀.

        β‘’ κ°ˆλ¦ΌκΈΈμ„ 순차적으둜 νƒμƒ‰ν•˜λ©° λ°˜λ³΅ν•œλ‹€.

        β‘£ 탐색에 성곡할 경우 μ’…λ£Œν•œλ‹€.

 

 

- 깊이 μš°μ„  탐색 (DFS) μž₯/단점

  β”” μž₯점 : ν˜„ κ²½λ‘œμƒμ˜ λ…Έλ“œλ§Œμ„ κΈ°μ–΅ν•˜λ―€λ‘œ μ €μž₯ κ³΅κ°„μ˜ μˆ˜μš”κ°€ 비ꡐ적 적음

                   νƒμƒ‰ λͺ©ν‘œμ˜ λ…Έλ“œκ°€ κΉŠμ€ 단계에 μžˆμ„ 경우 λΉ λ₯΄κ²Œ 탐색 κ°€λŠ₯

       λ‹¨μ  : ν•΄κ°€ μ—†λŠ” κ²½λ‘œμ— 깊이 빠질 κ°€λŠ₯성이 있음. (이럴 경우 미리 μ§€μ •ν•œ μž„μ˜ κΉŠμ΄κΉŒμ§€λ§Œ 탐색 ν›„ μ‹€νŒ¨ν•  경우 λ‹€μŒ 경둜 νƒμƒ‰ν•˜λŠ” 방법 μ‚¬μš©)

                   μ–»μ–΄μ§„ ν•΄κ°€ μ΅œλ‹¨ κ²½λ‘œκ°€ λœλ‹€λŠ” 보μž₯이 μ—†μŒ (DFS 방식은 해에 λ‹€λ‹€λ₯΄λŠ” 경우 탐색을 μ’…λ£Œν•˜λ―€λ‘œ 졜적이 아닐 κ°€λŠ₯μ„± 있음)

 

 

- DFS μ•Œκ³ λ¦¬μ¦˜ λ³΅μž‘λ„ [ V : λ…Έλ“œ 수  /  E : κ°„μ„  수 ]

  β”” μ‹œκ°„ λ³΅μž‘λ„ : O(V + E)

        곡간 λ³΅μž‘λ„ : O(V)

 

- DFS μ•Œκ³ λ¦¬μ¦˜

  β”” DFS의 κ΅¬ν˜„μ€ κ·Έλž˜ν”„ 각 μ •μ μ˜ λ°©λ¬Έ μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” κ²ƒμœΌλ‘œ λΆ„λ₯˜ν•œλ‹€.

        β‘  μŠ€νƒμ˜ μ΅œμƒλ‹¨μ— κ·Έλž˜ν”„μ˜ 정점 쀑 ν•˜λ‚˜λ₯Ό λ°°μΉ˜ν•œλ‹€

        β‘‘ μŠ€νƒμ˜ top에 μžˆλŠ” 정점을 가져와 λ°©λ¬Έ λͺ©λ‘μ— μΆ”κ°€ν•œλ‹€.

        β‘’ ν•΄λ‹Ή μ •μ μ˜ 인접 λ…Έλ“œ λͺ©λ‘μ„ 생성, λ°©λ¬Έ λͺ©λ‘μ— μ—†λŠ” 것을 μŠ€νƒμ˜ 상단에 μΆ”κ°€ν•œλ‹€.

        β‘£ μŠ€νƒμ΄ λΉ„μ–΄ μžˆμ„ λ–„κΉŒμ§€ ⑑와 β‘’ 반볡.

 

정점 0μ—μ„œ μ‹œμž‘ν•˜λŠ” 경우. 인접 λ…Έλ“œμΈ 1, 2, 3을 μŠ€νƒμ— μΆ”κ°€. 0은 λ°©λ¬Έν•œ κ²ƒμœΌλ‘œ ν‘œμ‹œ

 

0-1-2-4 μˆœμ„œλŒ€λ‘œ λ°©λ¬Έ ν›„ 인접 λ…Έλ“œκ°€ 없을 경우. 직전 λ…Έλ“œμΈ 0으둜 λŒμ•„κ°„ ν›„ 인접 λ…Έλ“œμΈ 3을 λ°©λ¬Έ

 

 

 

[ 깊이 μš°μ„  탐색 (DFS) μ•Œκ³ λ¦¬μ¦˜ κ΅¬ν˜„ ]

// C code
// μΈμ ‘ν–‰λ ¬λ‘œ ν‘œν˜„λœ 무ν–₯ κ·Έλž˜ν”„μ˜ DFS κ΅¬ν˜„
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAX_VERTICES 50

int visited[MAX_VERTICES]; // λ°©λ¬Έ μ—¬λΆ€λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•œ λ°°μ—΄

typedef struct GraphType {
    int n;	// μ •μ μ˜ 개수
    int adj_mat[MAX_VERTICES][MAX_VERTICES];
} GraphType;

// κ·Έλž˜ν”„ μ΄ˆκΈ°ν™” 
void init(GraphType* g) {
    int r, c;
    g->n = 0;
    for (r = 0; r < MAX_VERTICES; r++)
        for (c = 0; c < MAX_VERTICES; c++)
            g->adj_mat[r][c] = 0;
}

// 정점 μ‚½μž… μ—°μ‚°
void insert_vertex(GraphType* g, int v) {
    if (((g->n) + 1) > MAX_VERTICES) {
        fprintf(stderr, "κ·Έλž˜ν”„: μ •μ μ˜ 개수 초과");
        return;
    }
    g->n++;
}

// κ°„μ„  μ‚½μž… μ—°μ‚°
void insert_edge(GraphType* g, int start, int end) {
    if (start >= g->n || end >= g->n) {
        fprintf(stderr, "κ·Έλž˜ν”„: 정점 번호 였λ₯˜");
        return;
    }
    g->adj_mat[start][end] = 1;
    g->adj_mat[end][start] = 1;
}

// 인접 ν–‰λ ¬λ‘œ ν‘œν˜„λœ κ·Έλž˜ν”„μ— λŒ€ν•œ 깊이 μš°μ„  탐색
void dfs_mat(GraphType* g, int v) {
    int w;
    visited[v] = TRUE;            // 정점 v의 λ°©λ¬Έ 체크
    printf("정점 %d -> ", v);     // λ°©λ¬Έν•œ 정점 좜λ ₯
    for (w = 0; w < g->n; w++)    // 인접 λ…Έλ“œ 탐색
        if (g->adj_mat[v][w] && !visited[w])
            dfs_mat(g, w);        //정점 wμ—μ„œ DFS μƒˆλ‘œ μ‹œμž‘
}

int main(void){
    GraphType* g = (GraphType*)malloc(sizeof(GraphType));;
    init(g);

    for (int i = 0; i < 5; i++)
        insert_vertex(g, i);

    insert_edge(g, 0, 1);
    insert_edge(g, 0, 2);
    insert_edge(g, 0, 3);
    insert_edge(g, 1, 2);
    insert_edge(g, 2, 4);

    printf("<깊이 μš°μ„  탐색 (DFS)>\n");
    dfs_mat(g, 0);
    printf("\n");
    free(g);

    return 0;
}

 

 

 

[ λ„ˆλΉ„ μš°μ„  탐색 (BFS) ]

더보기

- λ„ˆλΉ„ μš°μ„  탐색 (BFS)

  β”” μ‹œμž‘ μ •μ μœΌλ‘œλΆ€ν„° μΈμ ‘ν•œ λ…Έλ“œλ₯Ό λ¨Όμ € 탐색, 멀리 λ–¨μ–΄μ Έ μžˆλŠ” λ…Έλ“œλ₯Ό λ‚˜μ€‘μ— λ°©λ¬Έν•˜λŠ” 탐색방법.

        주둜 큐λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„.

        β‘  루트 λ…Έλ“œμ—μ„œ μ‹œμž‘

        β‘‘ 루트 λ…Έλ“œμ˜ 인접 λ…Έλ“œλ“€μ˜ λͺ©λ‘μ„ 큐에 μ €μž₯

        β‘’ 인접 λ…Έλ“œ λͺ©λ‘μ˜ λ…Έλ“œλ“€μ„ μ°¨λ‘€λ‘œ λ°©λ¬Έ

        β‘£ β‘’λ²ˆ κ³Όμ •μ˜ 인접 λ…Έλ“œ λ°©λ¬Έμ‹œ ν•΄λ‹Ή 인접 λ…Έλ“œμ˜ 인접 λ…Έλ“œ(λ°©λ¬Έν•˜μ§€ μ•Šμ€) λͺ©λ‘μ„ 큐에 μ €μž₯

        β‘€ ν•΄λ‹Ή 과정을 반볡, λͺ¨λ“  λ…Έλ“œ λ°©λ¬Έμ‹œ 탐색 μ’…λ£Œ

 

- λ„ˆλΉ„ μš°μ„  탐색 (BFS) μž₯/단점

  β”” μž₯점 : μ—¬λŸ¬ 갈래 쀑 λ¬΄ν•œν•œ 길이λ₯Ό κ°€μ§€λŠ” κ²½λ‘œκ°€ μ‘΄μž¬ν•˜λ©° 탐색 λͺ©ν‘œκ°€ λ‹€λ₯Έ κ²½λ‘œμ— μ‘΄μž¬ν•  경우

                   DFS의 경우 탐색 λΆˆκ°€λŠ₯ν•˜μ§€λ§Œ BFS의 경우 λͺ¨λ“  경둜λ₯Ό λ™μ‹œμ— νƒμƒ‰ν•˜κΈ° λ•Œλ¬Έμ— 탐색 κ°€λŠ₯

                   λ…Έλ“œμ˜ μˆ˜κ°€ μ κ±°λ‚˜ κΉŠμ΄κ°€ μ–•μ„μˆ˜λ‘ 탐색에 유리(μ΅œμ„ μ˜ μƒν™©μ—μ„œ μ΅œμ„ μ˜ 탐색 κ°€λŠ₯)

                   λ‹¨μˆœ 검색 μ†λ„λŠ” 깊이 μš°μ„  탐색(DFS) 보닀 빠름

                   λ„ˆλΉ„λ₯Ό μš°μ„ μ μœΌλ‘œ νƒμƒ‰ν•˜κΈ°μ— 탐색 μ •μ μœΌλ‘œμ˜ κ²½λ‘œκ°€ μ—¬λŸ¬κ°œ 일지라도 μ΅œλ‹¨ 경둜λ₯Ό 보μž₯ κ°€λŠ₯

                   μ΅œλ‹¨ κ²½λ‘œκ°€ μ‘΄μž¬ν•  경우 μ–΄λŠ ν•œ κ²½λ‘œκ°€ λ¬΄ν•œνžˆ κΉŠμ–΄μ§€λ”λΌλ„ μ΅œλ‹¨ 경둜 탐색 κ°€λŠ₯

        단점 : μž¬κ·€ν˜ΈμΆœμ„ μ΄μš©ν•˜λŠ” DFS와 달리 큐에 λ‹€μŒ 탐색 λ…Έλ“œλ“€μ„ μ €μž₯ν•˜λ―€λ‘œ μ €μž₯ 곡간을 μƒλŒ€μ μœΌλ‘œ 많이 μ‚¬μš©

                    λ…Έλ“œμ˜ μˆ˜κ°€ λ§Žκ±°λ‚˜ κΉŠμ΄κ°€ κΉŠμ„μˆ˜λ‘ 탐색에 λΆˆλ¦¬ν•¨

 

- BFS μ•Œκ³ λ¦¬μ¦˜ λ³΅μž‘λ„ [ V : λ…Έλ“œ 수 / E : κ°„μ„  수 ]

  β”” μ‹œκ°„ λ³΅μž‘λ„ : O(V + E)

        곡간 λ³΅μž‘λ„ : O(V)

 

- BFS μ•Œκ³ λ¦¬μ¦˜

  β”” BFS의 κ΅¬ν˜„ λ˜ν•œ κ·Έλž˜ν”„ 각 μ •μ μ˜ λ°©λ¬Έ μ—¬λΆ€λ₯Ό 톡해 λΆ„λ₯˜

       β‘  μ‹œμž‘ μ •μ μ˜ 인접 λ…Έλ“œλ“€μ„ 큐에 μ €μž₯

       β‘‘ 큐에 μ €μž₯된 λ…Έλ“œ FRONT에 μœ„μΉ˜ν•œ λ…Έλ“œλ₯Ό λ°©λ¬Έ, ν•΄λ‹Ή λ…Έλ“œμ˜ λ°©λ¬Έν•˜μ§€ μ•Šμ€ 인접 λ…Έλ“œκ°€ μ‘΄μž¬ν•  경우 큐의 후단에 ν•΄λ‹Ή λ…Έλ“œ μ‚½μž…

       β‘’ 큐가 μ „λΆ€ λΉ„κ±°λ‚˜ λ°©λ¬Έ λͺ©λ‘μ΄ μ „λΆ€ μ°° λ•Œ κΉŒμ§€ β‘‘λ²ˆ 반볡.

 

 

루트 λ…Έλ“œ 0κ³Ό μΈμ ‘ν•œ λ…Έλ“œ 1, 2, 3을 큐에 μ‚½μž… ν›„ 큐의 FRONT λ…Έλ“œλΆ€ν„° 순차 탐색

 

2번 λ…Έλ“œ λ°©λ¬Έμ‹œ 인접 λ…Έλ“œ λͺ©λ‘ 쀑 λ°©λ¬Έν•˜μ§€ μ•Šμ€ 4번 λ…Έλ“œ 쑴재. ν•΄λ‹Ή λ…Έλ“œλ₯Ό 큐의 후단에 μ‚½μž… ν›„ 탐색 재개

 

 

[ λ„ˆλΉ„ μš°μ„  탐색 (BFS) μ•Œκ³ λ¦¬μ¦˜ κ΅¬ν˜„ ]

// C code
// μΈμ ‘ν–‰λ ¬λ‘œ ν‘œν˜„λœ 무ν–₯ κ·Έλž˜ν”„μ˜ BFS κ΅¬ν˜„
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAX_QUEUE_SIZE 10

typedef int element;
typedef struct { // 큐 νƒ€μž…
    element  queue[MAX_QUEUE_SIZE];
    int  front, rear;
} QueueType;

// 였λ₯˜ 검증 ν•¨μˆ˜
void error(char* message) {
    fprintf(stderr, "%s\n", message);
    exit(1);
}

// 큐 μ΄ˆκΈ°ν™” ν•¨μˆ˜
void queue_init(QueueType* q) {
    q->front = q->rear = 0;
}

// 곡백 μƒνƒœ 검증 ν•¨μˆ˜
int is_empty(QueueType* q) {
    return (q->front == q->rear);
}
// 포화 μƒνƒœ 검증 ν•¨μˆ˜
int is_full(QueueType* q) {
    return ((q->rear + 1) %
        MAX_QUEUE_SIZE == q->front);
}
// 큐 μ‚½μž… ν•¨μˆ˜
void enqueue(QueueType* q, element item) {
    if (is_full(q))
        error("큐가 ν¬ν™”μƒνƒœμž…λ‹ˆλ‹€");
    q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
    q->queue[q->rear] = item;
}
// 큐 μ‚­μ œ ν•¨μˆ˜
element dequeue(QueueType* q) {
    if (is_empty(q))
        error("큐가 κ³΅λ°±μƒνƒœμž…λ‹ˆλ‹€");
    q->front = (q->front + 1) % MAX_QUEUE_SIZE;
    return q->queue[q->front];
}

#define MAX_VERTICES 50
typedef struct GraphType {
    int n;	// μ •μ μ˜ 개수
    int adj_mat[MAX_VERTICES][MAX_VERTICES];
} GraphType;

int visited[MAX_VERTICES];

// κ·Έλž˜ν”„ μ΄ˆκΈ°ν™” ν•¨μˆ˜
void graph_init(GraphType* g) {
    int r, c;
    g->n = 0;
    for (r = 0; r < MAX_VERTICES; r++)
        for (c = 0; c < MAX_VERTICES; c++)
            g->adj_mat[r][c] = 0;
}

// 정점 μ‚½μž… μ—°μ‚°
void insert_vertex(GraphType* g, int v) {
    if (((g->n) + 1) > MAX_VERTICES) {
        fprintf(stderr, "κ·Έλž˜ν”„: μ •μ μ˜ 개수 초과");
        return;
    }
    g->n++;
}

// κ°„μ„  μ‚½μž… μ—°μ‚°
void insert_edge(GraphType* g, int start, int end) {
    if (start >= g->n || end >= g->n) {
        fprintf(stderr, "κ·Έλž˜ν”„: 정점 번호 였λ₯˜");
        return;
    }
    g->adj_mat[start][end] = 1;
    g->adj_mat[end][start] = 1;
}

// 인접 ν–‰λ ¬λ‘œ ν‘œν˜„λœ κ·Έλž˜ν”„μ— λŒ€ν•œ λ„ˆλΉ„ μš°μ„  탐색
void bfs_mat(GraphType* g, int v) {
    int w;
    QueueType q;
    queue_init(&q);       // 큐 μ΄ˆκΈ°ν™” 
    visited[v] = TRUE;    // 정점 v λ°©λ¬Έ ν‘œμ‹œ 
    printf("%d λ°©λ¬Έ -> ", v);
    enqueue(&q, v);       // μ‹œμž‘ 정점을 큐에 μ €μž₯ 
    while (!is_empty(&q)) {
        v = dequeue(&q);  // 큐에 정점 μΆ”μΆœ 
        for (w = 0; w < g->n; w++    // 인접 정점 탐색 
            if (g->adj_mat[v][w] && !visited[w]) {
                visited[w] = TRUE;   // λ°©λ¬Έ ν‘œμ‹œ
                printf("%d λ°©λ¬Έ -> ", w);
                enqueue(&q, w);      // λ°©λ¬Έν•œ 정점을 큐에 μ €μž₯
            }
    }
}

int main(void)
{
    GraphType* g;
    int i;
    g = (GraphType*)malloc(sizeof(GraphType));
    graph_init(g);
    for (i = 0; i < 5; i++)
        insert_vertex(g, i);

    insert_edge(g, 0, 1);
    insert_edge(g, 0, 2);
    insert_edge(g, 0, 3);
    insert_edge(g, 1, 2);
    insert_edge(g, 2, 4);

    printf("γ€Š λ„ˆλΉ„ μš°μ„  탐색 (BFS) 》\n");
    bfs_mat(g, 0);
    printf("\n");
    free(g);
    return 0;
}

 

μ €μž‘μžν‘œμ‹œ λΉ„μ˜λ¦¬ λ³€κ²½κΈˆμ§€ (μƒˆμ°½μ—΄λ¦Ό)
    'ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄/C' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
    • [자료ꡬ쑰] κ·Έλž˜ν”„
    • [자료ꡬ쑰] 트리 (2)
    • [자료ꡬ쑰] 트리 (1)
    • [자료ꡬ쑰] μ—°κ²°λ¦¬μŠ€νŠΈ (2)
    めけゃくけゃ ι–‹η™Ίθ€…πŸ¦Ύ
    めけゃくけゃ ι–‹η™Ίθ€…πŸ¦Ύ
    πŸ‘Š λΈ”λ‘œκ·Έλ„ 근성이닀? πŸ‘Š

    ν‹°μŠ€ν† λ¦¬νˆ΄λ°”