Computer Science/Problem Solving (PS)(38)
-
[백준 2188 | 포드-풀커슨] 축사 배정
풀이 소와 축사와의 관계를 네트워크 그래프로 정의하는 것이 핵심이 되는 문제였습니다. 가장 많은 축사가 채워지는 것을 Source와 Dest간의 최대 유량을 결정하는 문제로 바꾸어주면 포드-풀커슨 알고리즘을 통해 이 문제를 쉽게 해결할 수 있습니다. 아래 그림과 같이 Source에서 모든 Cow로 가는 간선이 있다고 하겠습니다. (아래 그림에서의 모든 간선의 가중치는 1이 됩니다.) Cow는 선호하는 Cage로 간선을 그릴 수 있으며 Source로부터 들어오는 Cow의 유량은 1이 되므로 여러 Cage로 가는 간선이 있다고 해도 결국에는 하나의 Cage밖에 선택할 수 없게 됩니다. 모든 Cage는 각각 Dest로 가는 가중치 1짜리 간선이 있습니다. 이 그래프에 따르면 가장 많은 우리가 채워지는 경우 =..
2020.07.08 -
[백준 6086 | 포드 풀커슨] 최대 유량
풀이 네트워크 유량과 관련된 기본적인 문제로, BFS를 사용하는 포드-풀커슨 알고리즘을 사용하여 구현하였습니다. 포드-풀커슨 알고리즘을 사용하여 이 문제를 해결 할 때의 주의점은, 파이프가 양쪽 모두로 물을 흘려보낼 수 있으므로, 파이프 하나를 양방향 간선으로 취급해야 한다는 점과, 동일한 파이프가 2개 이상 주어질 수 있다는 점입니다. 즉, A->B로 가는 용량 5짜리 파이프와 용량 2짜리 파이프가 동시에 입력될 수 있는데, 둘 중 어느 하나를 선택하는 것이 아니라 두 용량 모두를 더한 것이 A->B로 가는 파이프의 최종 용량이라는 것입니다. 소스 코드 (JAVA) import java.util.*; import java.io.*; /* @sckimynwa */ public class BOJ_6086 ..
2020.07.07 -
[백준 1647 | MST] 도시 분할 계획
풀이 이전 포스팅에서 다루었던 최소 스패닝 트리 문제를 아주 간단하게 응용하여 풀 수 있는 문제입니다. 최소 스패닝 트리를 이전과 마찬가지로 구하고 나서, 최소 스패닝 트리를 잇는 가장 가중치가 큰 간선을 제외하면 가장 작은 비용으로 두 마을을 나누어줄 수 있습니다. 따라서 최소 스패닝 트리를 생성할 때에 추가되는 간선의 가중치 중, 가장 큰 값을 저장해두었다가 트리의 생성 비용에서 제거해주면 됩니다. 소스 코드(JAVA) import java.util.*; import java.io.*; public class Kruskal { public static int[] parent; public static ArrayList edgeList; public static void main(String[] arg..
2020.06.27 -
[백준 1197 | MST] 최소 스패닝 트리
풀이 최소 스패닝 트리를 구하는 데에는 크게 2가지 알고리즘 (크루스칼 알고리즘, 프림 알고리즘)이 알려져 있습니다. 위 문제는 최소 스패닝 트리의 가중치 값을 묻는 기본적인 문제이기 때문에, 개인적으로 구현하기 편했던 크루스칼 알고리즘을 사용하였습니다. 크루스칼 알고리즘을 사용하기 위해서는 먼저 상호 배타적 집합 (Disjoint Set)을 먼저 구현해야 합니다. 크루스칼 알고리즘은 프림 알고리즘 과는 다르게, 간선을 가중치 순으로 먼저 정렬한 후에, 가중치가 작은 간선부터 이어 나가면서, 해당하는 간선의 두 정점이 이미 같은 트리에 속해 있는지를 판단해야 합니다. 예를 들어, 1과 2를 잇는 가중치 1인 간선을 추가하려고 할 때, 1과 2를 이어주는 경로가 이미 존재한다면 해당 간선을 추가해서는 안된..
2020.06.27 -
[백준 13544 | 머지 소트 트리] 수열과 쿼리 3
풀이 세그먼트트리를 응요한 자료구조인 머지 소트 트리(Merge Sort Tree)를 이용하면 O((logn)^2)시간 안에 해결할 수 있는 문제입니다. 머지 소트트리는 간단하게 말해서 트리의 각 노드에 자식들의 최솟값이나 최댓값을 저장하는 것이 아니라, 머지소트(Merge Sort)시에 일어나는 각 배열들의 중간 상태를 저장하는 자료 구조입니다. [5, 2, 4, 6, 1, 3, 2, 6]의 배열을 머지소트를 이용해서 정렬할 경우, 위의 그림과 같은 과정을 거치게 됩니다. 이 때, 각 노드의 상위 노드에는 두 배열을 머지하여 생긴 새로운 배열을 저장합니다. 즉 배열(혹은 리스트)의 배열 구조를 띄게 되는 것입니다. 이렇게 머지소트트리를 생성하고 난 후에는 쿼리를 날려서, 각 구간안에 포함되는 배열들 중..
2020.06.21 -
[백준 6549 | 세그먼트 트리] 히스토그램에서 가장 큰 직사각형
풀이 세그먼트 트리를 이용해 O(nlogn) 시간 안에 해결할 수 있는 문제입니다. 모든 세그먼트 트리 문제가 그렇듯, 각 구간에 저장할 정보가 무엇인지를 정하는 것이 문제 해결의 주 요소입니다. 입력받은 숫자들이 담겨 있는 배열의 전체 크기에 함수를 한번 호출하면, 그 함수들의 분할 정복을 통해 최대 직사각형의 넓이를 구하는 방식을 생각해 볼 수 있습니다. 예를 들어서 전체 8만큼의 크기를 갖는 배열이 있다고 할 때 (2 1 4 5 1 3 3 1) 전체 구간을 모두 포함하는 직사각형의 넓이와, 최소 높이를 갖는 인덱스를 기준으로 왼쪽 구간을 모두 포함하는 직사각형의 넓이와, 오른쪽 구간을 모두 포함하는 직사각형의 넓이를 비교하여 가장 큰 넓이를 갖는 사각형을 출력하면 되는 것입니다. 왼쪽 구간을 포함하..
2020.06.20