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

 

17396번: 백도어

첫 번째 줄에 분기점의 수와 분기점들을 잇는 길의 수를 의미하는 두 자연수 N과 M이 공백으로 구분되어 주어진다.(1 ≤ N ≤ 100,000, 1 ≤ M ≤ 300,000) 두 번째 줄에 각 분기점이 적의 시야에 보이는

www.acmicpc.net

최단거리 탐색 문제다. 다익스트라 알고리즘으로 접근했다.


풀이

접근 가능한 정점과 N-1번 정점을 이어주는 간선들만 저장했다.

 

swift에는 다른 언어들과 달리 Heap이 구현되어있지 않아서 일반적인 경우에는 일반 큐를 사용하여 매 순환마다 정렬 작업을 하여 탐색하였는데 이번 문제는 간선정보가 최대 300,000개가 주어지므로 Heap 구현이 필요했다.

 

글 읽기 - 다익스트라 시간초과 질문드립니다

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

그런데 마주한 시간초과. 질문게시판을 찾아보니 다익스트라 알고리즘의 원리를 잘 고민하면 우선순위 큐를 더 빠르게 탐색이 가능하다고 한다. 

 

우선 다익스트라 알고리즘은 비용이 낮은 순으로 정렬된 우선순위 큐를 탐색하여 매 순간 각 정점으로의 최소비용을 갱신하게 된다.

즉, [현재 정점의 최소비용 + 현재 정점에서 다음 정점까지의 비용] 계산을 통해 다음 정점의 최단거리 정보를 갱신하는데, 이때 우선순위 큐에서 꺼낸  현재 정점의 정보가 최소 비용이 아니라면 결국 다음 정점까지의 정보를 탐색할 필요가 없다는 얘기다.

 

따라서 매 탐색마다 최단거리 정보를 담고 있는 cost[curr]와 우선순위 큐에 담겨있는 curr.cost 와의 비교를 통해서 최단거리보다 큰 비용이라면 continue를 통해 시간단축이 가능하다.


정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[23286] 허들 넘기  (0) 2024.01.18
[5582] 공통 부분 문자열  (0) 2024.01.12
[23040] 누텔라 트리 (Easy)  (0) 2023.11.10
[20530] 양분  (0) 2023.11.04
[15559] 내 선물을 받아줘  (0) 2023.10.31

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

 

23040번: 누텔라 트리 (Easy)

첫째 줄에 트리의 정점의 개수 $N$이 주어진다. ($2 \le N \le 100\,000$) 이후 $(N-1)$개 줄에 걸쳐 각 간선이 잇는 두 정점의 번호 $u_i$, $v_i$가 공백을 사이에 두고 주어진다. ($1 \le u_i \le N$, $1 \le v_i \le N$,

www.acmicpc.net

유니온파인드와 그래프탐색으로 접근했다.


풀이

모든 정점을 방문하게 된다면 시간초과가 일어난다.

 

 

예제를 보면 3~1, 3~5, 3~4, 3~2, 6~4, 6~2 총 6개의 구간이 정답이다.

검은색 정점을 시작으로 빨간색 정점으로만 이어지는 경로의 개수. 즉 우리는 연속되는 빨간색 정점을 컴포넌트로 묶어 개수를 미리 저장해 놓으면 보다 빠르게 탐색이 가능해진다.

 

따라서 인접한 빨간색 정점끼리는 유니온을 통해 하나의 컴포넌트로 묶어내어 개수를 저장하고, 컴포넌트에 인접한 검은색 정점의 개수를 파악하면 해당 컴포넌트에서 발생되는 누텔라 트리의 개수를 구할 수 있게 된다. 

 

해당 과정은 bfs를 통해 O(N)만에 정답을 구할 수 있다.


정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[5582] 공통 부분 문자열  (0) 2024.01.12
[17396] 백도어  (0) 2023.12.27
[20530] 양분  (0) 2023.11.04
[15559] 내 선물을 받아줘  (0) 2023.10.31
[1765] 닭싸움 팀 정하기  (0) 2023.10.30

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

 

20530번: 양분

첫째 줄에 두 자연수 $N$, $Q$가 주어진다. 주어지는 그래프의 정점과 간선의 개수가 $N$개이며 쿼리가 $Q$개 주어진다는 것을 의미한다. 둘째 줄부터 $N$개의 줄에는 $i$번 간선이 연결하는 두 정점

www.acmicpc.net

그래프 탐색과 유니온파인드로 접근했다.


풀이

정점 N개와 간선 N개를 가진 트리는 한 개의 사이클을 가지고 있는 트리이다. 따라서 정점 u에서 v로 가는 경로가 사이클을 거쳐가게 된다면 경로는 2개가 되고, 경로에 사이클이 없다면 경로는 1개가 되는 것이다.

 

따라서 사이클에 속해있는 정점을 파악한 뒤 유니온 파인드를 수행하다. 연결하려 하는 두 정점의 경로가 사이클에 속한 경로라면, 정점을 연결하지 않고 넘어간 뒤, 쿼리가 주어질 때, 두 정점의 부모가 같다면 1 아니면 2를 출력하면 정답이다.

 

 

주어진 예제를 통해 보면 정점 1 - 2 - 3으로 사이클이 이루어진다. 따라서 정점 1, 2, 3 사이의 간선을 없애고 쿼리에서 서로 다른 컴포넌트의 경로를 물어보면 해당 경로는 사이클을 통한 경로가 있다는 뜻이므로 2를 출력, 같은 컴포넌트 내의 경로를 물어보면 1을 출력하면 된다.

 

사이클 검출은 진입차수가 1인 정점부터 너비 우선 탐색을 수행하여 찾아내었다. 


정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[17396] 백도어  (0) 2023.12.27
[23040] 누텔라 트리 (Easy)  (0) 2023.11.10
[15559] 내 선물을 받아줘  (0) 2023.10.31
[1765] 닭싸움 팀 정하기  (0) 2023.10.30
[23324] 어려운 모든 정점 쌍 최단 거리  (0) 2023.10.25

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

 

15559번: 내 선물을 받아줘

첫째 줄에 지도의 세로 크기 N과 가로 크기 M이 주어진다. (1 ≤ N, M ≤ 1,000, 1 < N×M ≤ 1,000,000) 둘째 줄부터 N개의 줄에는 구사과가 있는 곳의 지도가 주어진다.  지도에 쓰여 있는대로 이동했을

www.acmicpc.net

유니오 파인드와 그래프 탐색으로 접근했다.


풀이

2차원 지도를 1차원 배열로 매핑한 뒤 지도에 적힌 움직임 대로 그래프 탐색을 수행한다.

탐색을 수행하면서 현재 위치와 다음으로 이동할 위치의 번호끼리 합병해 주면 된다.

컴포넌트의 개수를 출력해 주면 정답이다.

 

단, 중복 방문을 막는 과정에서 실수하여 WA를 받았다.

반례는 문제에 주어진 예제를 보고 생각해 냈다.

 

3 4

SWWW

SEEN

EEEN

 

방문했던 위치여도 아직 방문하지 않은 곳에서 진입이 가능하기에 방문했던 위치도 무조건 유니온 동작을 수행해야 한다.


정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[23040] 누텔라 트리 (Easy)  (0) 2023.11.10
[20530] 양분  (0) 2023.11.04
[1765] 닭싸움 팀 정하기  (0) 2023.10.30
[23324] 어려운 모든 정점 쌍 최단 거리  (0) 2023.10.25
[23743] 방탈출  (0) 2023.10.01

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

 

1765번: 닭싸움 팀 정하기

1번 학생 혼자 팀, 2, 4, 6번 학생 셋이서 팀, 3, 5번 학생 둘이서 팀일 때, 팀의 개수가 최대이다.

www.acmicpc.net

유니온 파인드로 접근했다.


풀이

원수를 담는 배열 enemy 2차원 배열을 생성하여 원수 관계가 들어오면 양방향으로 추가.

친구 관계가 입력되면 유니온을 통해 컴포넌트를 합친다.

모든 입력이 들어오고 나면 enemy 배열을 탐색하면서 원수의 원수를 찾아 서로 연결해 주면 된다.

남아있는 컴포넌트의 개수를 출력하면 정답이다.


정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[20530] 양분  (0) 2023.11.04
[15559] 내 선물을 받아줘  (0) 2023.10.31
[23324] 어려운 모든 정점 쌍 최단 거리  (0) 2023.10.25
[23743] 방탈출  (0) 2023.10.01
[1833] 고속도로 설계하기  (0) 2023.09.30
 

23324번: 어려운 모든 정점 쌍 최단 거리

첫 번째 줄에 정점의 개수 $N$($2 \le N \le 100\,000$), 간선의 개수 $M$($1 \le M \le 200\,000$), 정수 $K$($1 \le K \le M$)가 주어진다. 다음 $M$개의 줄에 걸쳐 $u_i$와 $v_i$가 주어진다. 이것은 $i$번째 간선은 $u_i$

www.acmicpc.net

유니온 파인드로 접근하였다.


풀이

문제의 핵심은 가중치가 주어지는 간선은 오로지 한 개라는 것. 즉 가중치가 있는 간선을 거쳐가는 경로의 개수를 찾는 문제다. 가중치가 없는 간선들을 먼저 연결해 준 뒤 마지막으로 가중치가 존재하는 간선을 연결할 때, 연결하려는 두 컴포넌트의 개수를 서로 곱해주면 해당 간선을 거쳐가는 간선의 개수를 구할 수 있게 된다. 예제를 기준으로 그림으로 설명하면 다음과 같다.

 

1-2 연결
3-4 연결
4-5 연결
2-3 연결

2번 정점과 3번 정점을 연결할 때, 1-3, 1-4, 1-5, 2-3, 2-4, 2-5의 경로에서 2-3 간선을 이용해야만 한다. 즉 2번 정점이 속한 컴포넌트의 정점개수와 3번 정점이 속한 컴포넌트의 정점 개수를 서로 곱해주면 정답이다.

 

단, 예제입력 2와 같이 가중치가 존재하는 간선을 연결할 때 이미 두 정점이 같은 컴포넌트인 경우 비용 0인 간선으로 우회가 가능하기에 이때는 정답이 0이다.

 

따라서 유니온 파인드 알고리즘을 통해 각 컴포넌트의 개수를 핸들링하여 정답을 출력해 주면 된다.


정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[15559] 내 선물을 받아줘  (0) 2023.10.31
[1765] 닭싸움 팀 정하기  (0) 2023.10.30
[23743] 방탈출  (0) 2023.10.01
[1833] 고속도로 설계하기  (0) 2023.09.30
[16926] 배열 돌리기 1  (0) 2023.06.15

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

 

23743번: 방탈출

첫 번째 줄에는 방의 개수 $N$과 설치할 수 있는 워프의 개수 $M$이 주어진다. ($2 \le N \le 200\,000$, $1 \le M \le 100\,000$) 다음 $M$개의 줄에는 워프의 정보를 나타내는 세 정수 $a_i$, $b_i$, $c_i$가 공백으

www.acmicpc.net

기본적인 MST 문제다. 

 

풀이

두 가지 방법으로 풀었다. 첫 번째로 접근했던 방법은 시간이 조금 빠르지만 코드가 조금 더 길어진다. 

간선의 가중치가 작은 순서로 두 정점 U, V를 연결할 때, 조건을 추가했다. 

 

두 정점에 워프를 설치하는 비용 > 두 정점을 연결하는 간선 비용 + min( U정점에 워프 설치 비용, V정점에 워프 설치 비용)

 

두 정점에 탈출구 워프를 설치하는 비용이 더 저렴하다면 두 정점은 연결하지 않는다. 반대로 두 정점에 탈출구 워프 설치 비용이 더 비싸다면 간선을 연결하고 워프를 설치비용이 더 저렴한 쪽이 루트가 되어 연결하면 된다.

 

이후 각 컴포넌트의 루트 정점에 워프설치 비용을 더해주면 가장 작은( 간선 + 워프 설치 ) 비용이 나오는데, 마지막으로 한번 더 모든 정점에 워프 설치비용과 비교하여 더 작은 쪽을 출력하였다.

 

두 번째 방법은 탈출구를 0번 정점으로 취급하여 간선정보를 정렬한 뒤 MST를 수행하면 간단하게 구할 수 있다.

 

정답 코드-1

정답 코드 - 2

'Problem Solving > BOJ' 카테고리의 다른 글

[1765] 닭싸움 팀 정하기  (0) 2023.10.30
[23324] 어려운 모든 정점 쌍 최단 거리  (0) 2023.10.25
[1833] 고속도로 설계하기  (0) 2023.09.30
[16926] 배열 돌리기 1  (0) 2023.06.15
[3015] 오아시스 재결합  (0) 2023.06.12

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

 

1833번: 고속철도 설계하기

첫째 줄에 자연수 N이 주어진다. 다음 N개의 줄에는 인접행렬 형태로 두 도시 사이에 고속철도를 설치할 때 드는 비용이 주어진다. 이 비용은 각각 10,000을 넘지 않는 자연수이다. 만약 비용이 음

www.acmicpc.net

MST 알고리즘의 기본문제다. 크루스칼 알고리즘을 통해 해결했다.

유니온 함수의 구현에서 사소한 실수를 해서 WA를 받아 당황했지만 실수를 금방 발견했다.

 

풀이

주어지는 간선은 양방향 간선이므로 u (0 ..< N), v (u+1 ..< N) 탐색을 통해 중복되는 정보는 배제하고 탐색하였다.

 

간선이 음수면 이미 연결된 고속도로 이므로 절댓값을 totalCost에 더한 뒤, 두 정점을 연결한다. 주의할 점은 이미 부모가 같은 정점끼리의 간선이 음수로 주어질 수도 있으므로 있으므로 예외처리를 해주어야 한다.

 

나머지의 경우는 edges 배열에 담아낸 뒤 비용이 적은 간선부터 유니온 함수를 수행한다. 이때 연결된 간선은 배열에 따로 정보를 담아주었다가 출력해 주면 된다.

 

정답 코드

'Problem Solving > BOJ' 카테고리의 다른 글

[23324] 어려운 모든 정점 쌍 최단 거리  (0) 2023.10.25
[23743] 방탈출  (0) 2023.10.01
[16926] 배열 돌리기 1  (0) 2023.06.15
[3015] 오아시스 재결합  (0) 2023.06.12
[14890] 경사로  (0) 2023.06.03

+ Recent posts