티스토리 뷰

알고리즘

[ BOJ 1185 ] 유럽여행

dasu 2020. 12. 21. 20:29

링크

문제

1. 모든 마을을 최소 한 번씩은 방문해봐야 한다.

2. 반드시 출발한 곳으로 돌아와야 한다.

3. 출발점은 "임의로" 설정할 수 있다.


이 때 최소 코스트를 출력하라


풀이

핵심은 "다시 돌아와야 한다"라는 것이다.
일단, 출발점은 임의로 설정할 수 있고, MST 특성 상 어떤 곳에서 시작해도 상관이 없음을 생각하면
그냥 그리디스럽게 방문할 때 가장 작은 코스트가 드는 곳에서 시작하면 된다.
예제를 생각해보면, 4번 마을을 방문할 때 코스트가 6으로 제일 적으므로 4번에서 시작하는 것이다.
이제 어떻게 방문할지를 생각해봐야 한다.

관찰을 해보면, 다시 자기자신으로 돌아와야 한다는 특징 때문에, 간선을 무조건 "짝수"번 들러야 함을 알 수 있다.
MST 특성 상 사이클은 없으므로, 시작점 A에서 임의의 정점 A'에서 돌아오는 방법은 A->A'의 경로를 역순으로 오는 방법밖에 없다.
만약, 문제에서 마을을 방문할 때 가격이 추가가 안된다면 그냥 최소 스패닝 트리 구해가지고 가격 2배하면 된다.
하지만... 마을을 방문할 때 가격이 추가 된다...
따라서 다른 방법을 생각해야 한다.

앞의 발상을 좀 바꿔보자.
우리는 $a\leq b$이면 $2a\leq2b$가 됨이 자명하다.

즉, 스패닝 트리를 다 구해서 2배 하는 것이 아니라, 그냥 간선의 코스트 가격을 2배 하고 그 상황에서 MST를 구해도 큰 문제가 없다!

이를 응용해보자!

마을을 방문할 때 방문 정점의 가격을 추가해야함을 생각하고, 우리는 왕복했을 때의 가격을 한꺼번에 더해주므로

!!간선의 코스트를 $2\times cost[s][e]+visit[s]+visit[e]$로 설정해야한다

이 때, cost[s][e]는 s에서 e까지 가는데 소요되는 가격, visit[s]는 s 마을에 방문할 때 드는 cost(갔다가 오는 경우), visit[e]는 e 마을에 방문할 때 드는 cost(가는 경우)이다.

정확하게 풀어쓰면 $cost[s][e]+visit[e]$(S -> E)와 $cost[s][e]+visit[s]$ (E->S)이다.


간단하게 이렇게 간선 설정하고 MST 돌리면 된다. (필자는 크루스칼을 돌렸다)


코드


'알고리즘' 카테고리의 다른 글

[ BOJ 7453 ] 합이 0인 네 정수  (0) 2020.12.14
[ BOJ 1071 ] 소트  (0) 2020.08.30
[ BOJ 1941 ] 소문난 칠공주  (1) 2018.12.20
[ 오늘의 연습 ] 1. 622D  (0) 2018.07.31
[ 백준 5475, IOI 2007 Day 2 ] 광부들의 식사(Miners)  (0) 2018.07.10
댓글
최근에 올라온 글
공지사항
Total
Today
Yesterday
최근에 달린 댓글
링크
«   2024/05   »
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
글 보관함