본문 바로가기

Computer Science/Algorithm

(24)
[Algorithm] 단절점을 찾는 알고리즘과 단절선을 찾는 알고리즘이 미세하게 다른 이유 단절점과 단절선의 개념에 대해서는 스킵하겠습니다. 추후에 시간이 되면 올리겠습니다 ~ 본론으로 들어가서 단절점을 찾는 알고리즘과 단절선을 찾는 알고리즘이 왜 미세하게 다른 것일까요? 처음 단절점의 개념을 접하고나서 여러 블로그를 찾아봤었는데 단절선은 단절점 알고리즘에서 약간 변형만 하면 된다고 써놓고 코드만 올려놓은 블로그들이 대다수였습니다;;; 저같은 단절점 초보에게는 너무나도 매정한 설명이었습니다. 결론적으로 말하면 제가 이 포스팅을 하는 이유는 왜 단절선을 찾을 때는 부모 정점로 가는 간선을 제외하고 찾아야 하는가? 였습니다. 단절점을 찾을 때는 시작 정점에서 DST를 만들어 가면서 한 정점에서 부모 정점을 포함하여 뻗어나갈 수 있는 정점의 번호 중 가장 작은 값을 리턴시켜주는 알고리즘을 사용했습니..
[Algorithm] 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm) 플로이드 워셜 알고리즘은 다익스트라 알고리즘과 벨만포드 알고리즘과는 다르게 모든 정점사이의 최단 경로를 한 번에 구하는 알고리즘 입니다. 다익스트라와 벨만포드 알고리즘도 정점의 갯수번 만큼 돌리게 되면 모두 구할 수 있습니다. - 플로이드 워셜 알고리즘 기본적인 아이디어는 A->B로 가는 경로는 A->K->B(K는 경유지) K라는 경유지를 거쳐서 무조건 가게 된다는 생각이다. K는 그래프 상에 존재하는 모든 정점이 될 수 있다. 궁극적으로 A에서 K라는 경유지를 거쳐 B로 갈 수 있는 최단 거리를 구하는 것이다. D[i][j] 를 i에서 출발해 j까지 가는 최단 거리라고 했을 때, 다음 점화식을 만족한다. D[i][j] = min(D[i][j], D[i][k] + D[k][j]) https://www.a..
[Algorithm] 벨만-포드 알고리즘(Bellman-Ford Algorithm) 벨만 포드 알고리즘은 다익스트라 알고리즘과 다르게 음수 가중치가 있는 그래프에서도 모든 정점으로 가는 최단 거리를 찾을 수 있게 해줍니다. 하나의 출발점에서 출발하여 모든 지점으로 가는 최단 거리를 알 수 있습니다. 1. 벨만 포드 알고리즘 기본 아이디어는 그래프를 연결하고 있는 Edge를 기준으로 모든 정점으로 가는 최단 거리를 찾는 것입니다. 다익스트라가 정점 중심으로 최단 경로를 찾았다면 벨만 포드 알고리즘에서는 Edge들을 중심으로 찾습니다. 정점의 갯수를 V라 할 때, 한 정점에서 모든 정점을 방문할 수 있으려면 적어도 V-1번 방문해야 모든 정점을 방문할 수 있습니다. 따라서 모든 Edge들을 V-1번 보면서 각 정점의 최단 거리를 찾습니다. 다만 주의할 점은 만약 처음 D->C로가는 가중치 ..
[Algorithm] 다익스트라 알고리즘 (Dijkstra algorithm) 다익스트라 알고리즘은 최단경로를 탐색하는 알고리즘이며, 2차원 배열을 이용하여 구현시 O(N^2)의 시간복잡도를 가지고 힙(Heap)을 이용하여 구현하면 O(ElogN) 시간안에 탐색할 수 있는 알고리즘입니다. 다익스트라 알고리즘은 한 지점(S)에서 목적지 지점(E)로 이동할 수 있는 최단 경로를 탐색할 수 있으므로 단일 출발, 단일 도착 최단경로 문제에 활용될 수 있습니다. 단, 음수 가중치를 가지는 그래프에서는 사용할 수 없다는게 단점입니다. 왜 그런지는 잠시 뒤에 알아보겠습니다. 1. 다익스트라 알고리즘 시작점 S 에서 출발해 연결되어 있는 간선을 모두 방문한 뒤 해당 노드에 있는 값(경로 값, 초기 값은 무한대)보다 작으면 갱신시켜 줍니다. 그 다음 연결되어 있는 Edge 중에서 현재 가중치와 더..
[Algorithm] 최소 공통 조상 LCA (Lowest Common Ancestor) 최소 공통 조상이란? 최소 공통 조상(LCA)란 두 노드가 트리에서 두 노드를 포함하여 조상을 따라 거슬러 올라갈때 처음 공통으로 만나게 되는 정점이다. 아래 그림에서 5와 8의 LCA 는 바로 1이다. 그럼 어떻게 임의의 두 노드에 대해서 처음으로 같이 만나는 조상을 찾을 수 있을까? 처음으로 생각해 볼 수 있는 방법은 서로 만날 때까지 부모 노드를 따라서 두 노드를 옮겨 보는 것이다. 두 노드의 높이가 다르다면 높이를 맞춰주고 나서 하나씩 올려본다면 트리의 깊이를 H 라했을 때 찾는데 O(H)가 되고 최악의 경우 O(N) 의 시간을 가지게 된다. 더 빠르고 효율적으로 하는 방법은 없을까? DP 배열을 이용해서 O(logN) 시간에 구할 수 있다. 만약 두 노드의 15번째 조상이 서로 다르다면 1,2,..
[Algorithm] 인덱스 트리(Indexed Tree) 구간 합을 구하는 트리의 종류로 인덱스 트리, 세그먼트 트리, 펜윅 트리가 있다. 세그먼트 트리는 인덱스 트리가 포함하고 있는 한 종류이다. 세그먼트 트리로 풀 수 있는 문제는 인덱스 트리로 모두 풀 수 있다. 인덱스 트리란 ? 이진 트리의 한 종류로서 구간 합을 구하는데 쓰이는 자료구조. 예를 들어, 배열 A에 수열이 들어있고 구간 S-E 가 주어졌을때 ① A[S] - A[E] 의 구간합을 구하고 ② 구한 뒤 특정 A[i]번째 원소가 다른 숫자로 바뀐다. ①② 번 작업을 반복하는 일이 있을 때 인덱스 트리를 쓰게 된다. 만약 1,2,3,4 라는 수열이 배열에 들어있다고 하면 수의 갯수를 모두 리프노드에 넣을 수 있을만큼의 배열을 잡아야한다. 아래 그림에서 4,5,6,7 번에 1,2,3,4 가 들어가면 ..
[BOJ 14502] 연구소 이 문제는 3개의 벽을 맵에 세우고 바이러스가 퍼졌을 때 안전 구역의 최대 갯수를 구하는 문제이다. 벽은 안전구역에 설치할 수 있고 무조건 3개를 설치한다. 문제 풀이 : 벽을 세울 수 있는 3곳을 모두 만들어 본 뒤 바이러스 지역에서 bfs 를 돌려 바이러스를 퍼뜨리고 그 후에 안전 구역의 갯수를 계산했다. 시간복잡도는 N과 M 이 최대 8이므로 (8 X 8)^3 이다. 여기에 bfs를 돌리므로 8 ^2을 곱하면 8^8 = 2^24 =1677216 이다. 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747..
[BOJ 14503] 로봇 청소기 시뮬레이션 문제이다. 주어진 조건을 만족하게 로봇을 이동시킨다. 처음에 갈 수 있는 곳이 있는지 확인한 후에 갈 수 있을 때와 없을 때를 나누어 코딩했다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include #include using namespace std; int dx[] = {-1,0,1,0}; // up right down left int dy[] = { 0,1,..