ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 1260번] BFS, DFS
    Data Engineering/알고리즘 - Python 2021. 6. 29. 15:46

     

     

    [백준 1260번] DFS와 BFS]

     

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

     

    1260번: DFS와 BFS

    첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사

    www.acmicpc.net

     

     

    (정답)

    처음 해보는 문제라서 많이 어려워서 다른 답들을 참고했다.

    n,m,v=map(int,input().split())
    mat=[[0]*(n+1) for _ in range(n+1)]
    visit=[0]*(n+1)
    
    for i in range(m):
        x,y=map(int, input().split())
        mat[x][y]=mat[y][x]=1
    
    def dfs(start):
        visit[start]=1
        print(start, end=' ')
        for i in range(1,n+1):
            if visit[i]==0 and mat[start][i]==1:
                dfs(i)
    
    def bfs(start):
        queue=[start]
        visit[start]=1
    
        while queue:
            start=queue.pop(0)
            print(start, end=' ')
            for i in range(1,n+1):
                if visit[i]==0 and mat[start][i]==1:
                    queue.append(i)
                    visit[i]=1
    
    dfs(v)
    print()
    visit=[0]*(n+1)
    bfs(v)

     

     

    코드만 보면 복잡해보인다.

    DFS 부터 살펴보면서 궁금했던 점들을 정리해보자.

     

    (DFS 코드)

    n,m,v=map(int,input().split())
    mat=[[0]*(n+1) for _ in range(n+1)]
    visit=[0]*(n+1)
    
    for i in range(m):
        x,y=map(int, input().split())
        mat[x][y]=mat[y][x]=1
    
    def dfs(start):
        visit[start]=1
        print(start, end=' ')
        for i in range(1,n+1):
            if visit[i]==0 and mat[start][i]==1:
                dfs(i)
    
    dfs(v)

     

    (n+1) X (n+1) 행렬은 왜 만들까?

    코드의 행렬 구조 부터 살펴보자.

     

     

    📍코드에서 사용하는 행렬 원리

     

    → mat=[[0]*(n+1) for _ in range(n+1)]

     

     

    for i in range(n+1):

              x,y=map(int, input().split())

              mat[x][y]=mat[y][x]=1

     

     

     

     

    📍그래프에서 (1,2)(2,1)은 같다. 그래서 아래와 같은 대칭 행렬이 나오는 것이다.

       아래 행렬이 우리가 DFS에서 사용하는 것이다.

     

     

    빨간색 1~4그래프 정점의 번호이면서 인덱스 번호와 같다.

    (1,2)이 연결되었다면 mat[1][2] = mat[2][1] = 1 이 된다.

     

     

     

     

     

    📍간혹 n X n 행렬로 만들면 안되는지 궁금할 수 있는데, 만약 그렇게 되면

    (1,2)이 연결되었을 때 mat[0][1] = mat[1][0] = 1 이 된다.

       우리는 위와 같이 (n+1) X (n+1) 행렬을 사용할 때 더 편리함을 알 수 있다.

     

     


     

    (BFS 코드)

    n,m,v=map(int,input().split())
    mat=[[0]*(n+1) for _ in range(n+1)]
    visit=[0]*(n+1)
    
    for i in range(m):
        x,y=map(int, input().split())
        mat[x][y]=mat[y][x]=1
    
    def bfs(start):
        queue=[start]
        visit[start]=1
    
        while queue:
            start=queue.pop(0)
            print(start, end=' ')
            for i in range(1,n+1):
                if visit[i]==0 and mat[start][i]==1:
                    queue.append(i)
                    visit[i]=1
    
    bfs(v)

     

    📍whlie queue: 의 의미

    → queue 이름의 리스트에 원소가 없으면 반복을 중단한다.

       즉, 이어지는 정점이 없으면 멈추게 된다.

     

     

     

    📍queue 리스트를 사용하는 이유

    예제 입력2) (1,2) (3,1), (3,4) (5,2), (5,4)

    start=3, queue=[1,4 *queue.pop(0): 리스트의 가장 첫번째 요소를 선택해서 제거한다.

    start=1, queue=[4,2]  *큐 자료구조의 FIFO: 가장 먼저 입력된 데이터가 먼저 삭제된다.

    start=4, queue=[2,5]

    start=2, queue=[5]

    start=5, queue=[]  *queue에 원소가 없으므로 while문 종료

     

     

     

     

    📍리스트.pop(i)

    → 리스트의 해당 인덱스 요소를 제거한다.

    → i가 없으면 마지막 요소를 제거한다. ex) 리스트.pop()

     

     

     

     

     

     

    한 문제 만으로 BFS, DFS를 이해하지 못하는 것은 당연한 일이다.

    다른 문제들을 풀면서 조금씩 이해해나가도록 하자.

     

     

    댓글

Designed by Tistory.