본문 바로가기
코딩테스트 준비/백준 C#

백준C# - 1260 +) 풀이

by 코딩하는 돼징 2023. 12. 9.
반응형

DFS와 BFS를 구현하는 문제이다.

 

1. 초기 설정

01 graph와 visited 변수 설정

graph는 그래프를 표현하기 위한 인접리스트이고 vistied는 정점의 방문 여부를 나타내는 배열이다.

static List<int>[] graph;
static bool[] visited;

02 입력 받기

int[] input = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
int N = input[0]; // 정점
int M = input[1]; // 간선
int V = input[2]; // 탐색을 시작할 정점의 번호

03 그래프 초기화

graph = new List<int>[N + 1];
for (int i = 1; i <= N; i++)
{
    graph[i] = new List<int>();
}

 

만약 그래프를 초기화 안하면 어떻게 되나요?

그래프를 초기화하는 이유는 각 정점에 대한 빈 리스트가 생성되고 나중에 간선 정보를 추가할 수 있게 된다.

만약 초기화를 안하는 경우 graph[i]는 null값을 가지고 있게 된다. null값일때 요소를 추가하려고 하면 NullReferenceException이 발생한다.

초기화 안하는 경우 :graph[1] = null, graph[2] = null, ...
초기화 하는 경우 : graph[1] = [], graph[2] = [], ...

04 간선 정보 입력

for (int i = 0; i < M; i++)
{
    int[] edge = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
    int u = edge[0];
    int v = edge[1];

    graph[u].Add(v);
    graph[v].Add(u); // 양방향 간선이므로 반대 방향도 추가
}

05 오름차순으로 간선 정리

문제에서 정점이 낮은 순서대로 방문한다고 하였으므로 오름차순으로 간선을 정리한다.

for (int i = 1; i <= N; i++)
{
    graph[i].Sort();
    // Console.WriteLine($"graph[{i}] {string.Join(" ", graph[i])}");
}

2. DFS

01 DFS알고리즘

시작 노드에서 출발하여 한 경로를 따라 최대한 깊이 들어가며 탐색하는 알고리즘이다. 스택과 재귀로 구현된다.

 

C# - DFS(깊이우선탐색)개념 및 코드 구현

깊이 우선 탐색(DFS, Depth-First Search) 특정 노드에서 시작하여 그래프를 탐색하면서 제일 깊은 곳으로 들어갔다가 더 이상 들어갈 곳이 없게 되면 다시 돌아와 다른 경로로 탐색을 진행한다. 이를

code-piggy.tistory.com


02 DFS 코드

public static void DFS(int now)
{
    Console.Write(now + " ");
    visited[now] = true;

    foreach(int next in graph[now])
    {
        if (visited[next])
            continue;
        DFS(next);
    }
}

실행 과정

1) 현재 정점 now를 방문했다고 표시하고 해당 정점을 출력한다. 

2) 해당 정점의 이웃 정점들을 가져온 후 순차적으로 순회하며 방문하지 않은 이웃 정점이 있다면 해당 이웃 정점에 대해 DFS함수를 재귀적으로 호출한다.


3. BFS

01 BFS 알고리즘

시작 노드에서부터 인접한 노드들을 먼저 탐색하는 알고리즘이다. 큐를 사용해서 많이 구현된다.

 

C# - BFS(너비우선탐색)개념 및 코드 구현

너비우선탐색(BFS, Breadth-First Search) 시작 노드로부터 인접한 노드를 먼저 모두 방문한 후 그 인접한 노드들의 근처 노드들을 차례대로 방문하는 방식으로 동작한다. DFS같은 경우 많은 곳에 사용

code-piggy.tistory.com


02 BFS 코드

public static void BFS(int start)
{
    Queue<int> queue = new Queue<int>();
    queue.Enqueue(start);
    visited[start] = true;
    while (queue.Count > 0)
    {
        int now = queue.Dequeue();
        Console.WriteLine(now + " ");

        foreach (int next in graph[now])
        {
            if (!visited[next])
            {
                queue.Enqueue(next);
                visited[next] = true;
            }
        }
    }
}

 

실행 과정

1) 시작 정점 추가한다음 방문했다고 표시

2) 큐에 현재 정점 추출

3) 현재 정점에서 방문하지 않은 이웃 정점 큐에 추가 및 방문했다고 표시

4) 2 - 3 번 반복 큐가 비면 반복문 종료


코드 전문

using System;
using System.Collections.Generic;

namespace baek2
{

   class Program 
   {
        static bool[] visited;
        static List<int>[] graph;
        public static void DFS(int now)
        {
            Console.Write(now + " ");
            visited[now] = true;

            foreach(int next in graph[now])
            {
                if (visited[next])
                    continue;
                DFS(next);
            }
        }

        public static void BFS(int start)
        {
            Queue<int> queue = new Queue<int>();
            queue.Enqueue(start);
            visited[start] = true;
            while (queue.Count > 0)
            {
                int now = queue.Dequeue();
                Console.Write(now + " ");

                foreach (int next in graph[now])
                {
                    if (!visited[next])
                    {
                        queue.Enqueue(next);
                        visited[next] = true;
                    }
                }
            }

        }
        public static void Main()
        {
            int[] input = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
            int N = input[0]; 
            int M = input[1]; 
            int V = input[2];
            graph = new List<int>[N + 1];
            for (int i = 1; i <= N; i++)
            {
                graph[i] = new List<int>();
            }

            for (int i = 0; i<M;i++)
            {
                int[] edge = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
                int u = edge[0];
                int v = edge[1];

                graph[u].Add(v);
                graph[v].Add(u);
            }
            for (int i = 1; i <= N; i++)
            {
                graph[i].Sort();
            }
            
            visited = new bool[N + 1];
            DFS(V);
            Console.WriteLine();
            visited = new bool[N + 1];
            BFS(V);
        }
   }
}

 

반응형

'코딩테스트 준비 > 백준 C#' 카테고리의 다른 글

백준 C# - 1707 +) 풀이  (0) 2023.12.10
백준 C# - 11724 +) 풀이  (0) 2023.12.10
백준 C# - 9465 +) 풀이  (1) 2023.12.07
백준 C# - 11057  (0) 2023.12.07
백준 C# - 1309 +) 풀이  (0) 2023.12.04

댓글