문제 제목 : DFS와 BFS

난이도 : 하

문제 유형 : DFS, BFS

추천 풀이 시간 : 30분 (못하면 2배 60분)

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

 

1260번: DFS와 BFS

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

www.acmicpc.net

 

import java.util.*;

public class Main {
    public static Integer n, m, v;
    public static ArrayList<ArrayList<Integer>> adjList = new ArrayList<>();
    public static boolean[] visited = new boolean[1001];

    public static void addEdge(int n, int m) {
        adjList.get(n).add(m);
    }

    public static void dfs(int node) {
        if (visited[node]) return;

        visited[node] = true;
        System.out.print(node + " ");

        for (int i = 0; i < adjList.get(node).size(); i++) {
            dfs(adjList.get(node).get(i));
        }
    }

    public static void bfs(int node) {
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.offer(node);
        visited[node] = true;
        while (!queue.isEmpty()) {
            int now = queue.poll();
            System.out.print(now + " ");
            for (int i = 0; i < adjList.get(now).size(); i++) {
                int adjNode = adjList.get(now).get(i);
                if (!visited[adjNode]) {
                    queue.offer(adjNode);
                    visited[adjNode] = true;
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        v = sc.nextInt();

        for (int i = 0; i < n + 1; i++) {
            adjList.add(new ArrayList<Integer>());
        }

        for (int i = 0; i < m; i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            addEdge(x, y);
            addEdge(y, x);
        }

        for (int i = 1; i < n + 1; i++) {
            Collections.sort(adjList.get(i));
        }

        dfs(v);
        System.out.println();
        visited = new boolean[1001];
        bfs(v);
    }
}

'Algorithm > BAEKJOON' 카테고리의 다른 글

[알고리즘-DFS,BFS] 바이러스  (0) 2023.01.24
[알고리즘-BFS] 숨바꼭질  (0) 2023.01.24
[알고리즘-DP] 가장 높은 탑 쌓기  (0) 2023.01.23
[알고리즘-DP] 기타리스트  (0) 2023.01.23
[알고리즘-DP] LCS  (0) 2023.01.21

1. BFS와 DFS

대표적인 그래프 탐색 알고리즘

너비 우선 탐색 (Breadth First Search) : 정점들과 같은 레벨에 있는 노드들 (형제 노드들)을 먼저 탐색하는 방식

깊이 우선 탐색 (Depth First Search) : 정점과 자식들을 먼저 탐색하는 방식

 

출처 :&nbsp;https://fastcampus.co.kr/courses/210773/clips/

 

2. DFS 구현

import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class Main3 {
    public static Integer node;
    public static ArrayList<ArrayList<Integer>> adj =  new ArrayList<>();
    public static Boolean visited[] = new Boolean[node];

    public static void addEdge (Integer node1, Integer node2) {
        adj.get(node1).add(node2);
    }

    public static void dfs (Integer node) {
        if (visited[node]) return;

        visited[node] = true;
        System.out.println(node + " ");

        for (int i = 0; i < adj.get(node).size(); i++) {
            int adjNode = adj.get(node).get(i);
            dfs(adjNode);
        }
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        node = sc.nextInt();

        for (int i = 0; i < node + 1; i++) {
            adj.add(new ArrayList<Integer>());
        }

        Integer node2 = sc.nextInt();

        addEdge(node, node2);
    }
}

 

3. 시간 복잡도

노드수 : V

간선수 : E

시간 복잡도 : O(V + E)

'Algorithm > 알고리즘' 카테고리의 다른 글

병합 정렬  (0) 2023.02.05
퀵정렬  (0) 2023.02.05
너비 우선 탐색 (BFS)  (0) 2023.01.23
그래프(Graph)  (0) 2023.01.23
동적 계획법 (Dynamic Programming)과 분할 정복 (Divide and Conquer)  (0) 2023.01.20

1. BFS와 DFS

대표적인 그래프 탐색 알고리즘

너비 우선 탐색 (Breadth First Search) : 정점들과 같은 레벨에 있는 노드들 (형제 노드들)을 먼저 탐색하는 방식

깊이 우선 탐색 (Depth First Search) : 정점과 자식들을 먼저 탐색하는 방식

 

출처 :&nbsp;https://fastcampus.co.kr/courses/210773/clips/

 

2. BFS 구현

import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class Main {
    public static Integer node;
    public static ArrayList<ArrayList<Integer>> adj =  new ArrayList<>();

    public static void addEdge (Integer node1, Integer node2) {
        adj.get(node1).add(node2);
    }

    public static void bfs (Integer newNode) {
        Boolean visited[] = new Boolean[node];
        LinkedList<Integer> queue = new LinkedList<Integer>();

        visited[newNode] = true;
        queue.add(newNode);

        while (!queue.isEmpty()) {
            int now = queue.poll();
            System.out.println(now + " ");
            for (int i = 0; i < adj.get(now).size(); i++) {
                int adjNode = adj.get(now).get(i);
                if (!visited[adjNode]) {
                    visited[adjNode] = true;
                    queue.add(adjNode);
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        node = sc.nextInt();

        for (int i = 0; i < node + 1; i++) {
            adj.add(new ArrayList<Integer>());
        }

        Integer node2 = sc.nextInt();

        addEdge(node, node2);
    }
}

 

3. 시간 복잡도

노드수 : V

간선수 : E

시간 복잡도 : O(V + E)

'Algorithm > 알고리즘' 카테고리의 다른 글

퀵정렬  (0) 2023.02.05
깊이 우선 탐색 (DFS)  (0) 2023.01.23
그래프(Graph)  (0) 2023.01.23
동적 계획법 (Dynamic Programming)과 분할 정복 (Divide and Conquer)  (0) 2023.01.20
재귀 용법 (recursive call)  (0) 2023.01.20

1. 그래프(Graph) 란?

그래프는 실제 세계의 현상이나 사물을 정점(Vertex) 또는 노드(Node)와 간선(Edge)로 표현하기 위해 사용

 

2. 그래프(Graph) 관련 용어

  • 노드(Node) : 위치를 말함, 정점(Vertex)라고도 함
  • 간선(Edge) : 위치 간의 관계를 표시한 선으로 노드를 연결한 선이라고 보면 됨 (link 또는 branch라고도 함)
  • 인접 정점(Adjacent Vertex) : 간선으로 직접 연결된 정점(또는 노드)
  • 참고 용어
    • 정점의 차수(Degree) : 무방향 그래프에서 하나의 정점에 인접한 정점의 수
    • 진입 차수(In-Degree) : 방향 그래프에서 외부에서 오는 간선의 수
    • 진출 차수(Out-Degree) : 방향 그래프에서 외부로 향하는 간선의 수
    • 경로 길이(Path Length) : 경로를 구성하기 위해 사용된 간선의 수
    • 단순 경로(Simple Path) : 처음 정점과 끝 정점을 제외하고 중복된 정점이 없느 경로
    • 사이클(Cycle) : 단순 경로의 시작 정점과 종료 정점이 동일한 경우

 

3. 그래프(Graph) 종류

무방향 그래프

방향이 없는 그래프

간선을 통해 노드는 양방향으로 갈 수 있음

보통 노드 A, B가 연결되어 있을 경우 (A, B) 또는 (B, A)로 표기

 

방향 그래프

간선에 방향이 있는 그래프

보통 노드 A, B가 A -> B로 가는 간선으로 연결되어 있을 경우 <A, B>롤 표기

 

가중치 그래프 또는 네트워크

간선에 비용 또는 가중치가 할당된 그래프

 

연결 그래프

무방향 그래프에 있는 모든 노드에 대해 항상 경로가 존재하는 경우

 

비연결 그래프

무방향 그래프에서 특정 노드에 대해 경로가 존재하지 않는 경우

 

사이클

단순 경로의 시작 노드와 종료 노드가 동일한 경우

 

비순환 그래프

사이클이 없는 그래프

 

완전 그래프

그래프와 모든 노드가 서로 연결되어 있는 그래프

 

4. 그래프와 트리의 차이

트리는 그래프 속에 속한 특별한 종류하고 볼 수 있음

  그래프 트리
정의 노드와 노드를 연결하는 간선으로 표현되는 자료 구조 그래프의 한 종류, 방향성이 있는 비순환 그래프
방향성 방향 그래프, 무방향 그래프 둘 다 존재 방향 그래프만 존재
사이클 사이클 가능함, 순환 및 비순환 그래프 모두 존재 비순환 그래프로 사이클 존재하지 않음
루트 노드 루트 노드 존재하지 않음 루트 노드 존재함
부모/자식 관계 부모 자식 개념이 존재하지 않음 부모 자식 관계가 존재

문제 제목 : 가장 높은 탑 쌓기

난이도 : 상

문제 유형 : 동적 프로그래밍(DP), LIS

추천 풀이 시간 : 50분 (못하면 2배 100분)

TIP : 가장 적은 경우의 수부터 계산을 해본 후 패턴을 찾아 점화식을 세우자@@

점화식이란? 이웃하는 두개의 항 사이에 성립하는 관계를 나타낸 관계식 예를들어 dp[n + 2] = dp[n + 1] + dp[n + 2]

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

 

2655번: 가장높은탑쌓기

첫째 줄에는 입력될 벽돌의 수가 주어진다. 입력으로 주어지는 벽돌의 수는 최대 100개이다. 둘째 줄부터는 각 줄에 한 개의 벽돌에 관한 정보인 벽돌 밑면의 넓이, 벽돌의 높이 그리고 무게가 차

www.acmicpc.net

 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;

public class Main {
    public static class Brick {
        public Integer index;
        public Integer area;
        public Integer height;
        public Integer weight;

        public Brick(Integer index, Integer area, Integer height, Integer weight) {
            this.index = index;
            this.area = area;
            this.height = height;
            this.weight = weight;
        }
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        Integer n = sc.nextInt();
        ArrayList<Brick> brickList = new ArrayList<Brick>();

        brickList.add(new Brick(0, 0, 0, 0));
        for (int i = 1; i < n + 1; i++) {
            brickList.add(new Brick(i, sc.nextInt(), sc.nextInt(), sc.nextInt()));
        }

        Collections.sort(brickList, (s1, s2) -> s1.weight - s2.weight);

        int[] dp = new int[n + 1];
        dp[0] = 0;

        for (int i = 1; i < n + 1; i++) {
            for (int j = 0; j < i; j++) {
                if (brickList.get(i).area > brickList.get(j).area) {
                    dp[i] = Math.max(dp[i], dp[j] + brickList.get(i).height);
                }
            }

        }

        Integer maxHeight = Arrays.stream(dp).max().getAsInt();

        int index = n;
        ArrayList<Integer> resultList = new ArrayList<>();
        while (index != 0) {
            if (maxHeight == dp[index]) {
                resultList.add(brickList.get(index).index);
                maxHeight -= brickList.get(index).height;
            }
            index -= 1;
        }

        System.out.println(resultList.size());
        for (int i = resultList.size() - 1; i >= 0; i--) {
            System.out.println(resultList.get(i));
        }
    }
}

'Algorithm > BAEKJOON' 카테고리의 다른 글

[알고리즘-BFS] 숨바꼭질  (0) 2023.01.24
[알고리즘-DFS,BFS] DFS와 BFS  (0) 2023.01.23
[알고리즘-DP] 기타리스트  (0) 2023.01.23
[알고리즘-DP] LCS  (0) 2023.01.21
[알고리즘-DP] 가장 긴 증가하는 부분 수열  (0) 2023.01.21

문제 제목 : 기타리스트

난이도 : 중

문제 유형 : 동적 프로그래밍(DP

추천 풀이 시간 : 40분 (못하면 2배 80분)

TIP : 가장 적은 경우의 수부터 계산을 해본 후 패턴을 찾아 점화식을 세우자@@

점화식이란? 이웃하는 두개의 항 사이에 성립하는 관계를 나타낸 관계식 예를들어 dp[n + 2] = dp[n + 1] + dp[n + 2]

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

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Integer n = sc.nextInt();
        Integer s = sc.nextInt();
        Integer m = sc.nextInt();
        ArrayList<Integer> diffList = new ArrayList<Integer>();
        int[][] dp = new int[51][1001];
        
        for (int i = 0; i < n; i++) {
            diffList.add(sc.nextInt());
        }
        
        dp[0][s] = 1;
        
        for (int i = 1; i < n + 1; i++) {
            for (int j = 0; j < m + 1; j++) {
                if (dp[i - 1][j] == 0) continue;
                if (j - diffList.get(i - 1) >= 0) {
                    dp[i][j - diffList.get(i - 1)] = 1;
                }
                if (j + diffList.get(i - 1) <= m) {
                    dp[i][j + diffList.get(i - 1)] = 1;
                }
            }
        }
        
        int result = -1;
        for (int i = m; i >= 0; i--) {
            if (dp[n][i] == 1) {
                result = i;
                break;
            }
        }
        
        System.out.println(result);
    }
}

문제 제목 : LCS

난이도 : 하

문제 유형 : 동적 프로그래밍(DP), LCS

추천 풀이 시간 : 30분 (못하면 2배 60분)

TIP : 가장 적은 경우의 수부터 계산을 해본 후 패턴을 찾아 점화식을 세우자@@

점화식이란? 이웃하는 두개의 항 사이에 성립하는 관계를 나타낸 관계식 예를들어 dp[n + 2] = dp[n + 1] + dp[n + 2]

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

 

9251번: LCS

LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

www.acmicpc.net

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();
        String str2 = sc.nextLine();
        int[][] dp = new int[1001][1001];
        
        for (int i = 1; i < str1.length() + 1; i++) {
            for (int j = 1; j < str2.length() + 1; j++) {
                if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
                }
            }
        }
        
        System.out.println(dp[str1.length()][str2.length()]);
    }
}

문제 제목 : 가장 긴 증가하는 부분 수열

난이도 : 하

문제 유형 : 동적 프로그래밍(DP), LIS

추천 풀이 시간 : 30분 (못하면 2배 60분)

TIP : 가장 적은 경우의 수부터 계산을 해본 후 패턴을 찾아 점화식을 세우자@@

점화식이란? 이웃하는 두개의 항 사이에 성립하는 관계를 나타낸 관계식 예를들어 dp[n + 2] = dp[n + 1] + dp[n + 2]

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

 

11053번: 가장 긴 증가하는 부분 수열

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이

www.acmicpc.net

 

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int result = 0;
        ArrayList<Integer> a = new ArrayList<Integer>();
        int[] dp = new int[1000];
        
        for (int i = 0; i < n; i++) {
            a.add(sc.nextInt());
        }
        for (int i = 0; i < n; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (a.get(i) > a.get(j)) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            result = Math.max(result, dp[i]);
        }  

        System.out.println(result);
    }
}

'Algorithm > BAEKJOON' 카테고리의 다른 글

[알고리즘-DP] 기타리스트  (0) 2023.01.23
[알고리즘-DP] LCS  (0) 2023.01.21
[알고리즘-DP] 평범한 배낭  (0) 2023.01.21
[알고리즘-DP] 01타일  (0) 2023.01.21
[알고리즘-DP] 파도반 수열  (0) 2023.01.20

+ Recent posts