Notice
Recent Posts
Recent Comments
Link
250x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 너비우선탐색
- Two Pointers
- ccw
- Bitmasking
- 소수
- 백준
- binary search
- 큐
- CCW 알고리즘
- 다익스트라
- 알고리즘
- 에라토스테네스
- 이진 탐색
- 딕셔너리
- BOJ
- BFS
- 에라토스테네스의 체
- 비트마스킹
- Python
- 투 포인터
- 위상정렬
- dijkstra algorithm
- DP
- Algorithm
- 비트연산
- 재귀
- 외적
- CCW알고리즘
- deque
- recursion
Archives
- Today
- Total
꾸꾸리
[BOJ/Python] 21924_도시 건설 본문
728x90
문제 출처:https://www.acmicpc.net/problem/21924
문제
채완이는 신도시에 건물 사이를 잇는 양방향 도로를 만들려는 공사 계획을 세웠다.
공사 계획을 검토하면서 비용이 생각보다 많이 드는 것을 확인했다.
채완이는 공사하는 데 드는 비용을 아끼려고 한다.
모든 건물이 도로를 통해 연결되도록 최소한의 도로를 만들려고 한다.

위 그림에서 건물과 직선으로 표시된 도로, 해당 도로를 만들 때 드는 비용을 표시해놓은 지도이다.

그림에 있는 도로를 다 설치할 때 드는 비용은 62이다. 모든 건물을 연결하는 도로만 만드는 비용은 27로 절약하는 비용은 35이다.
채완이는 도로가 너무 많아 절약되는 금액을 계산하는 데 어려움을 겪고 있다.
채완이를 대신해 얼마나 절약이 되는지 계산해주자.
입력

출력
예산을 얼마나 절약 할 수 있는지 출력한다. 만약 모든 건물이 연결되어 있지 않는다면 -1을 출력한다.
예제 입력 1
7 9
1 2 15
2 3 7
1 3 3
1 4 8
3 5 6
4 5 4
4 6 12
5 7 1
6 7 6
예제 출력 1
35
예제 입력 2
8 10
1 2 4
2 3 9
2 4 9
3 4 4
3 5 1
4 6 14
6 7 5
5 7 3
7 8 7
6 8 3
예제 출력 2
30
예제 입력 3
5 4
1 2 1
2 3 1
3 1 1
4 5 5
예제 출력 3
-1
풀이
모든 건물들이 도로를 통해 연결되도록 하여야 한다.
여기서 도로의 비용의 합이 최소가 되도록 하여야 하므로, 최소 신장 트리를 구하는 문제임을 알 수 있다.
이 문제에서는 만들어진 도로의 비용의 합을 구하는 것이 아닌 얼마만큼 절약하였는지를 구하는 문제이므로, 연결되지 않은 도로의 비용의 합을 구하여 출력하면 된다.
코드는 다음과 같다.
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
|
import sys
def find_parent(parent,x):
if parent[x]!=x:
parent[x] = find_parent(parent,parent[x])
return parent[x]
def union_parent(parent,a,b):
a = find_parent(parent,a)
b = find_parent(parent,b)
if a<b:
parent[b] = a
else:
parent[a] = b
n,m = map(int,sys.stdin.readline().split())
parent = [i for i in range(n+1)]
edges=[]
for _ in range(m):
edges.append(tuple(map(int,sys.stdin.readline().split())))
edges.sort(key=lambda x:x[2])
l = 0
result = 0
for a,b,c in edges:
if l==n-1:
result+=c
else:
if find_parent(parent,a)!=find_parent(parent,b):
union_parent(parent,a,b)
l+=1
else:
result+=c
if l<n-1:
result = -1
print(result)
|
cs |
- 두 건물과 연결되어 있는 도로의 정보를 입력받아 (도시 1, 도시 2, 도로의 비용)의 튜플 형태로 만들어 edges 리스트에 추가한다.
- edges 리스트를 도로의 비용을 기준으로 오름차순으로 정렬한다.
- 만약 n-1개의 간선이 연결되었다면 최소 신장 트리가 완성되었으므로, 이후에 나오는 간선들은 연결되지 않는 간선들이므로 result에 해당 도로의 비용을 더해준다.
- 아직 최소 신장 트리가 완성되지 않은 경우라면, 두 도로가 같은 집합인지 확인한다.
- 같은 집합이 아니라면 union_parent 함수를 이용하여 하나의 집합으로 합친다.
- 만약 같은 집합이라면 도로를 추가로 연결하게 되면 사이클이 생기므로 최소 비용이 아니게 되므로, 도로를 연결하지 않는다. 따라서 이 도로는 사용하지 않으므로 result에 현재 도로의 비용을 더해준다.
- 최종적으로 간선들을 다 살펴봤을 때, 연결된 간선의 개수가 n-1개 보다 작다면 연결되지 않은 건물이 존재한다는 뜻이므로 result를 -1로 바꾼다.
- result를 출력한다.
728x90
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ/Python] 1766_문제집 (1) | 2023.03.07 |
---|---|
[BOJ/Python] 16236_아기 상어 (0) | 2023.03.06 |
[BOJ/Python] 14621_나만 안되는 연애 (0) | 2023.03.05 |
[BOJ/Python] 4386_별자리 만들기 (0) | 2023.03.04 |
[BOJ/Python] 1197_최소 스패닝 트리 (0) | 2023.03.03 |