백준 1446[자바] java 지름길
문제 링크:https://www.acmicpc.net/problem/1446
1446번: 지름길
첫째 줄에 지름길의 개수 N과 고속도로의 길이 D가 주어진다. N은 12 이하인 양의 정수이고, D는 10,000보다 작거나 같은 자연수이다. 다음 N개의 줄에 지름길의 시작 위치, 도착 위치, 지름길의 길이
www.acmicpc.net
▶문제
매일 아침, 세준이는 학교에 가기 위해서 차를 타고 D킬로미터 길이의 고속도로를 지난다. 이 고속도로는 심각하게 커브가 많아서 정말 운전하기도 힘들다. 어느 날, 세준이는 이 고속도로에 지름길이 존재한다는 것을 알게 되었다. 모든 지름길은 일방통행이고, 고속도로를 역주행할 수는 없다.
세준이가 운전해야 하는 거리의 최솟값을 출력하시오.
▶입력
첫째 줄에 지름길의 개수 N과 고속도로의 길이 D가 주어진다. N은 12 이하인 양의 정수이고, D는 10,000보다 작거나 같은 자연수이다. 다음 N개의 줄에 지름길의 시작 위치, 도착 위치, 지름길의 길이가 주어진다. 모든 위치와 길이는 10,000보다 작거나 같은 음이 아닌 정수이다. 지름길의 시작 위치는 도착 위치보다 작다.
▶출력
세준이가 운전해야하는 거리의 최솟값을 출력하시오.
▶해설
DP로만 풀수 있을줄 알았는데 N,D의 값이 작아서 DFS를 이용해서 풀 수 있는 문제입니다. 조건을 살펴보겠습니다.
1. 고속도로의 끝에 딱 맞춰서 끝나야한다. (ex 150이라면 150에 맞춰서 끝나야됨)
2. 지름길 시작지점에서만 진입할 수 있다.
저는 DFS로 접근해보겠습니다.
DFS로 접근하기 위해서는 3가지의 분기점이 있습니다.
1. 지금까지 온 길이 고속도로의 끝을 넘었을 때
2. 지금까지 온 길이 고속도로의 끝과 딱 맞을때
3. 지금까지 온 길이 고속도로의 끝보다 작을 때
1번: DFS를 아무런 조치하지 않고 종료하면됩니다.
if(now>end){ return; }
2번: 지금까지 이동한 거리와 기록중에 최소값을 구해주면 됩니다.
else if(now==end){ result= Math.min(result,distance); return; }
3번: (고속도로의 끝지점 - 지금까지 온 길) + 지금까지 이동한 거리와 기록을 비교해줍니다.
이 경우는 현재 조건을 만족하는 지름길이 없거나, 지름길을 선택하지 않았을 때 끝지점까지 이동하는 거리를 구하는 것입니다. 따라서 지름길을 이후에 선택할 수도 있기 때문에 DFS를 종료하지 않습니다.
else{ result = Math.min(result, distance+(end-now)); }
이제 지름길을 방문했는지 따져보고, 지름길의 시작지점이 내가 현재 있는 위치와 같은지 판단합니다. 조건에 부합할 경우 지름길의 끝을 우리가 앞으로 시작할 지점으로 넣고, 지나온 거리에 지름길의 값을 넣어줍니다. 만약 지름길을 선택하지 않았다면, 현재 위치+1, 지금까지 지나온 거리+1 을 해주므로써 1거리 만큼 간 것을 다음 DFS로 넘겨줍니다.
for(int i=0; i<paths.size(); i++){ if(!check[i]){ Path path = paths.get(i); if(path.start==now){ check[i]=true; dfs(path.end, m, distance+ path.cost); check[i]=false; } } } dfs(now+1, m, distance+1);
전체 코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; class Path{ int start; int end; int cost; public Path(int start, int end, int cost) { this.start = start; this.end = end; this.cost = cost; } } public class Main { static List<Path> paths; static int n,m; static int result = Integer.MAX_VALUE; static boolean [] check; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] s = br.readLine().split(" "); n = Integer.parseInt(s[0]); m = Integer.parseInt(s[1]); paths = new ArrayList<>(); int start,end, cost; for(int i=0; i<n; i++){ String[] s1 = br.readLine().split(" "); start = Integer.parseInt(s1[0]); end = Integer.parseInt(s1[1]); cost = Integer.parseInt(s1[2]); if(start>m || end>m){ continue; } paths.add(new Path(start,end,cost)); } check = new boolean[paths.size()]; dfs(0,m,0); System.out.println(result); } private static void dfs(int now, int end, int distance){ if(now>end){ return; } else if(now==end){ result= Math.min(result,distance); return; } else{ result = Math.min(result, distance+(end-now)); } for(int i=0; i<paths.size(); i++){ if(!check[i]){ Path path = paths.get(i); if(path.start==now){ check[i]=true; dfs(path.end, m, distance+ path.cost); check[i]=false; } } } dfs(now+1, m, distance+1); } }
'Alogorithm > 최단 경로' 카테고리의 다른 글
백준 11265[자바] java 끝나지 않은 파티 (0) | 2022.05.31 |
---|---|
백준 2224 [자바] java 명제 증명 (0) | 2022.01.31 |
백준 1719 [자바] java 택배 (0) | 2022.01.14 |
백준 14938 [자바] java 서강그라운드 (0) | 2022.01.08 |
백준 JAVA 11657번 타임머신 (0) | 2021.12.19 |
댓글
이 글 공유하기
다른 글
-
백준 11265[자바] java 끝나지 않은 파티
백준 11265[자바] java 끝나지 않은 파티
2022.05.31문제 링크: https://www.acmicpc.net/problem/11265 11265번: 끝나지 않는 파티 입력의 첫 번째 줄에는 파티장의 크기 N(5 ≤ N ≤ 500)과 서비스를 요청한 손님의 수 M(1 ≤ M ≤ 10,000) 이 주어진다. 각각의 파티장은 1번부터 N번까지 번호가 붙여져 있다. 다음에는 N개의 줄에 걸 www.acmicpc.net ▶문제 파티를 좋아하는 민호는 끝없이 파티가 열리는 놀이동산 "민호 월드"를 세웠다. 처음에는 한 개의 파티장만을 가지고 있는 작은 놀이동산이었지만, 사람들의 점점 많이 찾아와 파티장을 증축했고 현재는 N개의 파티장을 가진 큰 놀이동산이 되었다. 민호는 파티장을 증축할 때마다 편의를 위해 새로운 파티장과 기존의 모든 파티장이 직접적으로 연결이 될 수… -
백준 2224 [자바] java 명제 증명
백준 2224 [자바] java 명제 증명
2022.01.31문제 링크: https://www.acmicpc.net/problem/2224 2224번: 명제 증명 첫째 줄에 출력할 명제의 개수 X개를 출력한다. 다음 X개의 줄에 증명될 수 있는 명제를 한 줄에 하나씩 출력한다. 명제를 출력할 때에는 전건 순으로 정렬하고, 전건이 같은 경우에는 후건 순으 www.acmicpc.net ▶문제 수학, 혹은 논리학에서 만약 무엇이라면 뭣 일 것이다 하는 식의 명제가 널리 쓰인다. 예를 들어 "P이면 Q일 것이다."라는 명제는 “P => Q”라는 기호로 표현된다. 이때의 P를 전건, Q를 후건이라고 한다. 논리학에서 어떤 명제를 증명할 때 가장 널리 쓰이는 방법 중 한 가지가 바로 삼단 논법이다. 만약 두 명제 “P => Q", "Q => R" 가 모두 참이면, 명제 "P… -
백준 1719 [자바] java 택배
백준 1719 [자바] java 택배
2022.01.14 -
백준 14938 [자바] java 서강그라운드
백준 14938 [자바] java 서강그라운드
2022.01.08
댓글을 사용할 수 없습니다.