목차
- 개요
- 본문
- 1) 문제
- 2) 과정
- 3) 코드 전체
개요
이번에 알고리즘 스터디에서 JAVA를 이용해 백준 18352번 특정 거리의 도시 찾기를 풀었습니다. 이를 정리해보고자 합니다.
18352번: 특정 거리의 도시 찾기
첫째 줄에 도시의 개수 N, 도로의 개수 M, 거리 정보 K, 출발 도시의 번호 X가 주어진다. (2 ≤ N ≤ 300,000, 1 ≤ M ≤ 1,000,000, 1 ≤ K ≤ 300,000, 1 ≤ X ≤ N) 둘째 줄부터 M개의 줄에 걸쳐서 두 개
www.acmicpc.net
본문
1) 문제

2) 과정
18352번은 다익스트라 알고리즘의 기본흐름을 이해하니까 30분도 안되서 에러도 없이 한번에 풀어냈던 아주 간단한 문제였습니다! 제가 사용한 아이디어는 최단거리를 계산할 때 많이 사용하는 다익스트라 알고리즘의 틀 그 자체와 다를바 없기 때문에 그 흐름을 설명하는 걸로 말해보며 마무리하고자 합니다.
0) initialize arrays
- 간선을 연결짓는 정보는 ArrayList[]를 사용해 저장하고, 탐색을 위한 큐는 PriorityQueue를 사용한다.
- 그리고 최단거리를 담는 dp 배열은 Integer.MAX_VALUE로 채워두고 추가로 방문체크를 위한 visited까지 만들어둔다.
1) initialize first value
- 큐에 첫 위치를 시작거리인 0과 함께 담고
- dp도 첫 위치를 0으로 정해 초기값을 셋팅한다.
2) check Condition - 큐를 통해 값을 전달하며 방문여부와 다음위치가 있는지 여부를 체크
3) check possibility for the next - 현재 위치에서 다음위치까지의 거리를 계산한 값(cnt+1)이 다음위치에 저장된 최단거리(dp[next])보다 작다면 이를 큐와 dp로 갱신해주길 반복
4) print output - 모든 탐색이 끝이 나면 dp에 저장된 값이 k(원하는 최단 거리)인 인덱스를 StringBuilder에 담고 이 크기가 0이라면 -1 아니라면 그 인덱스들을 오름차순으로 출력
Input,Logic,Output으로 문제 풀이를 나눠볼게요 :) 주석으로 충분히 설명한 것 같아서 따로 설명은 달지 않겠습니다.
2-1) Input
public static void main(String[] args) throws IOException {
// Input
MyIO io = new MyIO();
io.readLine();
int n = io.nextInt(); // 도시의 개수
int m = io.nextInt(); // 도로의 개수
int k = io.nextInt(); // 원하는 최단 거리
int x = io.nextInt(); // 출발 도시 번호
ArrayList<Integer>[] orgArr = new ArrayList[n+1]; // 간선의 연결정보를 담을 배열
for(int i=0;i<m;i++){
io.readLine();
int a = io.nextInt();
int b = io.nextInt();
// a->b
if(orgArr[a]==null) orgArr[a]=new ArrayList<>();
orgArr[a].add(b);
}
}
// Inner Class - Read & Write values
private static class MyIO{
// Variable
BufferedReader br;
StringTokenizer st;
// Constuctor
public MyIO(){br = new BufferedReader(new InputStreamReader(System.in));}
// Method - for input
public void readLine() throws IOException { st = new StringTokenizer(br.readLine());}
public int nextInt(){ return Integer.parseInt(st.nextToken());}
}
2-2) Logic & Output
// Logic
// initialize arrays
Queue<int[]> q = new PriorityQueue<>((o1,o2)->Integer.compare(o1[1], o2[1])); // 탐색을 위한 큐
int[] dp = new int[n+1]; // 최단 거리를 담아낼 dp 배열
Arrays.fill(dp, Integer.MAX_VALUE); // dp의 초기값을 int의 최대값으로 채운다.
boolean[] visited = new boolean[n+1]; // 방문여부를 체크할 배열
// initialize first value
q.add(new int[]{x,0});
dp[x]=0;
// start searching
while(!q.isEmpty()){
int[] cur = q.poll();
int pos = cur[0]; // 현재 위치
int cnt = cur[1]; // 현재 위치까지의 거리 크기
// check Condition - 방문여부 체크
if(visited[pos]) continue;
visited[pos] = true;
// check possibility for the next - 다음 도시가 있는지 체크
if(orgArr[pos]==null) continue;
for(int next : orgArr[pos]){
// next의 현재까지의 최소값보다 새롭게 계산한 값이 더 작다면
if(dp[next]>cnt+1){
// 큐와 dp에 갱신
q.add(new int[]{next,cnt+1});
dp[next] = cnt+1;
}
}
}
// Output - dp값이 k인게 없으면 -1아니면 인덱스를 출력
StringBuilder sb = new StringBuilder();
for(int i=1;i<=n;i++)if(dp[i]==k) sb.append(i+"\n");
System.out.println(sb.length()==0?-1:sb.toString());
3) 전체코드
그렇게 완성된 코드는 아래쪽에 링크된 깃헙 레포짓토리에 방문하여 확인해주세요!
소요시간, 아이디어, 에러로그 등 더 자세히 보실 수 있습니다.
https://github.com/Park1122/Algorithm-Study/blob/master/sujeong/shortest_path/BOJ18352.java
GitHub - Park1122/Algorithm-Study: 명지대학교 학생들이 모여서 만든 알고리즘 공부 및 코딩테스트 준비
명지대학교 학생들이 모여서 만든 알고리즘 공부 및 코딩테스트 준비를 위한 스터디입니다. Contribute to Park1122/Algorithm-Study development by creating an account on GitHub.
github.com
'알고리즘(JAVA 사용) > Shortest Path' 카테고리의 다른 글
[알고리즘풀이]백준 11265 : 끝나지 않는 파티 JAVA (0) | 2022.01.04 |
---|---|
[알고리즘풀이]백준 1916 : 최소비용 구하기 JAVA (0) | 2021.12.31 |
[알고리즘풀이]백준 1753 : 최단경로 JAVA (0) | 2021.12.31 |
[알고리즘풀이]백준 11403 : 경로 찾기 JAVA (0) | 2021.12.31 |