본문 바로가기

분류 전체보기

(84)
백준 1043 거짓말 www.acmicpc.net/problem/1043 1043번: 거짓말 지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게 www.acmicpc.net 이 문제는 유니온 파인드+BFS 또는 비트마스킹을 통해 해결할 수 있다. 유니온 파인드를 모른다면 본 블로그의 해당 포스팅을 읽어보길 바란다. 아래의 그림을 보자 문제에 주어진 바와 같이, 파티 3개를 구성했다. 그리고 파티에 참가하는 인원들을 모두 엮어서 그래프로 표현할 수 있다. 2-3-4는 같은 파티에 참가하므로 사이클을 이루고, 1과 2가 같이 파티에 참가하므로 연결된다. 가장 중심에 있는 2가 만약에 진실을 알고..
유니온 파인드 (Union-Find) (disjoint set) (분리 집합) 유니온 파인드는 익히기도 쉽고, 응용 범위도 넓어서 아주 좋아하는 편이다. 간단한 유파는 구현도 쉽고. 꼭 PS가 아니라도 프로그래밍을 하다 보면, 뭔가 동시적으로 (concurrently or simultaneously) 값을 바꾸는 등의 작업을 구현하고 싶을 때가 참 많다. 2가 1의 자식 노드인데, 1의 값을 변경함으로써 2도 어떠한 처리를 해주거나, 우선순위 큐에 이미 들어있는 값인데, 어떤 처리를 통해 그 안의 값이 바뀌면서 순서가 역전되거나, 복잡하게 얽힌 그래프 속에서 하나의 정점만 바꿔도 그 안에 연결된 모든 정점을 같이 바꾼다거나,... 그럴 때 마치 집합처럼 정점들을 엮어주고, 빠르게 처리를 해줄 수 있는 것이 바로 유니온 파인드이다. 유니온 파인드는 유니온 함수와 파인드 함수 2가지를..
LIS - 가장 긴 증가하는 부분 수열 LIS는 이분탐색을 사용하는 기법이다. Longest Increasing Subsequence의 약자로써, 가장 긴 증가하는 부분 수열을 의미한다. 이에 대해 이해하면, 사실 가장 긴 감소하는 부분 수열에도 똑같이 응용 가능하다. [어떤 수를 어디에 놓을지]를 이분탐색으로 해결하는 것이 핵심이다. 위의 그림과 같이, [4, 2, 1, 5, 6, 3] 이라는 수열이 있다고 예를 들자. 이때 가장 긴 증가하는 부분 수열을 찾고자 할 때, 위에 일일이 적은 대로 앞에서부터 하나씩 골라서 확인해볼 수 있을 것이다. 그럼 방식은 2중 for-loop구조를 갖게 되므로, O(n^2)의 시간복잡도를 갖게 된다. 당연히 좋은 방법이 아니다. 위의 그림을 보자. 가장 긴 증가하는 부분 수열을 담을 LIS벡터 또는 배열을..
백준 2352 반도체 설계 www.acmicpc.net/problem/2352 2352번: 반도체 설계 첫째 줄에 정수 n(1 ≤ n ≤ 40,000)이 주어진다. 다음 줄에는 차례로 1번 포트와 연결되어야 하는 포트 번호, 2번 포트와 연결되어야 하는 포트 번호, …, n번 포트와 연결되어야 하는 포트 번호가 주 www.acmicpc.net 이 문제는 이런 유형을 아예 처음 보았다면 이것이 LIS인지 쉽게 떠올리기 어려울 수도 있다. LIS에 대한 내용은 이전 포스팅에서 정리해두었으니 참조 부탁드린다. 위와 같이, 1에서 시작한 선은 4로 연결되고, 3에서 시작한 선은 6에서 끝난다. 그 시작점과 끝점을 두줄에 걸쳐 나열하였다. 윗줄에 1, 2, 3, 4, 5, 6을 굳이 쓴 이유는 출발점이 증가하는 순서대로 나열되어있다는 것을..
백준 19238 스타트 택시 (삼성 기출) www.acmicpc.net/problem/19238 19238번: 스타트 택시 첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다 www.acmicpc.net 약간의 자료구조 설계와 BFS를 주로 사용하여 해결할 수 있다. 항상 그렇듯이, 이러한 구현 문제는 문제의 조건을 신경 써서 잘 읽고, 흐름과 스토리를 잘 파악해야 한다. 주요한 조건들은 아래와 같다 - 승객을 고를 때는 최단거리에 있는 승객을 선택한다. - 승객마다 가고자 하는 목적지가 있고, 거기까지는 무조건 이동한다. (그 승객의 목적지가 멀다고 승차거부 등을 하지 ..
백준 4196 도미노 www.acmicpc.net/problem/4196 4196번: 도미노 도미노는 재밌다. 도미노 블록을 일렬로 길게 늘어세운 뒤 블록 하나를 넘어뜨리면 그 블록이 넘어지며 다음 블록을 넘어뜨리는 일이 반복되어 일렬로 늘어선 블록들을 연쇄적으로 모두 쓰러 www.acmicpc.net 본 블로그 SCC관련 포스팅에서 num값이 크면 가장 멀리 있는 정점까지 도달할 수 있는 가능성이 있다고 하였다. 약간 위상정렬에서 순서가 가장 앞서는 정점에서 시작해야 모든 정점을 돌 수 있는 것처럼, SCC를 찾을 때 첫 번째 DFS에서 매겨둔 num값 중 가장 큰 값에서 시작하면 가장 멀리 갈 가능성이 있다. (절대 항상 그런건 아니다. 주의!) 이 도미노 문제는 어떠한 블록을 넘어뜨리면 가장 멀리 가는 경우 (또는 가장..
강한 연결 요소 - Strongly Connected Component (SCC) 개인적으로 그래프, 트리 등을 좋아하는 편이다. 이 알고리즘도 그래서 매우 재미있게 익힐 수 있었다. 강한 연결 요소는 DG (Directed Graph, 단방향 그래프)에서 사이클을 찾는 방법이다. 그리고 그 사이클은 포함할 수 있는 모든 정점을 최대한으로 포함시켜준다. - 사이클을 이룰 수 있는 최대 크기 파악 가능 (하나의 사이클을 이루는 최대한 많은 정점 모두 포함) - 사이클의 총 개수 - 사이클을 이루는 정점 번호 - 사이클을 하나의 정점으로 치환 후 위상정렬과의 연계 등등 다양한 기능을 수행한다. 본 포스팅에서는 코사라주 알고리즘으로 SCC를 찾아보겠다. 기본적인 방식은 DFS를 통해 하나의 정점에서 도달할 수 있는 최대한 먼 곳에서 가까운 순으로 번호를 달아주고, 역방향 그래프 상에서 다시..
백준 6543 그래프의 싱크 www.acmicpc.net/problem/6543 6543번: 그래프의 싱크 각 테스트 케이스마다 한 줄에 걸쳐 bottom(G)의 모든 노드를 출력한다. 노드는 공백으로 구분해야 하며, 오름차순이어야 한다. 만약, bottom(G)가 공집합이면 빈 줄을 출력한다. www.acmicpc.net 이 문제는 SCC를 활용할 수 있는 문제이며, 본 블로그 내의 SCC 관련 포스팅을 꼭 같이 참조하기 바란다. 이 문제는 SCC를 찾기만 하는 게 아니다. SCC를 이루는 요소에서 다른 정점 어디라도 갈 수 있는데, 돌아오지 못한다면 답이 아니게 된다. 위의 그림은 이전 SCC포스팅에서 사용한 그림이다. 위와 같은 그래프에서는 1-2-3이 원래 SCC를 이루지만, 3에서 4와 5도 갈 수 있고, 4와 5에서는 1..