-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[241129] BOJ 16166 서울의 지하철 #1029
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
124 changes: 124 additions & 0 deletions
124
ys4512558/Week_45/BOJ_16166_서울의지하철/BOJ_16166_서울의지하철.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.util.*; | ||
|
||
public class Main { | ||
static Map<Long, List<Edge>> adjMap; | ||
static int N; | ||
static long dest; | ||
|
||
public static void main(String[] args) throws IOException { | ||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | ||
N = Integer.parseInt(br.readLine()); | ||
|
||
adjMap = new HashMap<>(); | ||
|
||
//PQ를 통한 탐색 | ||
//해당 번호(Long)가 갈 수 있는 엣지를 담는 맵을 통해 임의 접근 | ||
for (int i = 0; i < N; i++) { | ||
StringTokenizer st = new StringTokenizer(br.readLine()); | ||
int cnt = Integer.parseInt(st.nextToken()); | ||
long pre = Long.parseLong(st.nextToken()); | ||
for (int j = 0; j < cnt - 1; j++) { | ||
long cur = Long.parseLong(st.nextToken()); | ||
Edge edge = new Edge(i, pre, cur); | ||
List<Edge> edgeList = adjMap.getOrDefault(pre, new ArrayList<>()); | ||
edgeList.add(edge); | ||
adjMap.put(pre, edgeList); | ||
//양방향 | ||
edge = new Edge(i, cur, pre); | ||
edgeList = adjMap.getOrDefault(cur, new ArrayList<>()); | ||
edgeList.add(edge); | ||
adjMap.put(cur, edgeList); | ||
pre = cur; | ||
} | ||
} | ||
dest = Long.parseLong(br.readLine()); | ||
System.out.println(dest == 0 ? 0 : dijkstra()); | ||
} | ||
|
||
private static int dijkstra() { | ||
PriorityQueue<Info> pq = new PriorityQueue<>(); | ||
List<Edge> edgeList = adjMap.getOrDefault(0L, new ArrayList<>()); | ||
for (int i = 0; i < edgeList.size(); i++) { | ||
Edge edge = edgeList.get(i); | ||
Info info = new Info(edge.num, edge.v, 0); | ||
info.set.add(info); | ||
pq.offer(info); | ||
} | ||
int res = -1; | ||
while (!pq.isEmpty()) { | ||
Info info = pq.poll(); | ||
|
||
if (info.v == dest) { | ||
res = info.cnt; | ||
break; | ||
} | ||
|
||
List<Edge> edges = adjMap.getOrDefault(info.v, new ArrayList<>()); | ||
for (int i = 0; i < edges.size(); i++) { | ||
Edge edge = edges.get(i); | ||
|
||
List<Edge> nexts = adjMap.getOrDefault(edge.u, new ArrayList<>()); | ||
Info next = new Info(edge.num, edge.u, info.cnt + ((edge.num == info.num) ? 0 : 1)); | ||
if (!info.set.add(next)) continue; | ||
next.set = new HashSet<>(info.set); | ||
pq.offer(next); | ||
for (int j = 0; j < nexts.size(); j++) { | ||
Edge nextEdge = nexts.get(j); | ||
next = new Info(nextEdge.num, nextEdge.v, next.cnt + ((nextEdge.num == next.num) ? 0 : 1)); | ||
Set<Info> set = new HashSet<>(info.set); | ||
if (set.add(next)) { | ||
next.set = set; | ||
pq.offer(next); | ||
} | ||
} | ||
} | ||
} | ||
return res; | ||
} | ||
} | ||
|
||
//이동 경로 정보 저장 | ||
class Info implements Comparable<Info> { | ||
int num; | ||
long v; | ||
int cnt; | ||
Set<Info> set = new HashSet<>(); //isv | ||
|
||
public Info(int num, long v, int cnt) { | ||
this.num = num; | ||
this.v = v; | ||
this.cnt = cnt; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Info info = (Info) o; | ||
return num == info.num && v == info.v; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(num, v); | ||
} | ||
|
||
@Override | ||
public int compareTo(Info o) { | ||
return Integer.compare(this.cnt, o.cnt); | ||
} | ||
} | ||
|
||
class Edge { | ||
int num; //호선 | ||
long v, u; //v -> u; | ||
|
||
public Edge(int num, long v, long u) { | ||
this.num = num; | ||
this.v = v; | ||
this.u = u; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
# 소스코드 | ||
|
||
```Java | ||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.util.*; | ||
|
||
public class Main { | ||
static Map<Long, List<Edge>> adjMap; | ||
static int N; | ||
static long dest; | ||
|
||
public static void main(String[] args) throws IOException { | ||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | ||
N = Integer.parseInt(br.readLine()); | ||
|
||
adjMap = new HashMap<>(); | ||
|
||
//PQ를 통한 탐색 | ||
//해당 번호(Long)가 갈 수 있는 엣지를 담는 맵을 통해 임의 접근 | ||
for (int i = 0; i < N; i++) { | ||
StringTokenizer st = new StringTokenizer(br.readLine()); | ||
int cnt = Integer.parseInt(st.nextToken()); | ||
long pre = Long.parseLong(st.nextToken()); | ||
for (int j = 0; j < cnt - 1; j++) { | ||
long cur = Long.parseLong(st.nextToken()); | ||
Edge edge = new Edge(i, pre, cur); | ||
List<Edge> edgeList = adjMap.getOrDefault(pre, new ArrayList<>()); | ||
edgeList.add(edge); | ||
adjMap.put(pre, edgeList); | ||
//양방향 | ||
edge = new Edge(i, cur, pre); | ||
edgeList = adjMap.getOrDefault(cur, new ArrayList<>()); | ||
edgeList.add(edge); | ||
adjMap.put(cur, edgeList); | ||
pre = cur; | ||
} | ||
} | ||
dest = Long.parseLong(br.readLine()); | ||
System.out.println(dest == 0 ? 0 : dijkstra()); | ||
} | ||
|
||
private static int dijkstra() { | ||
PriorityQueue<Info> pq = new PriorityQueue<>(); | ||
List<Edge> edgeList = adjMap.getOrDefault(0L, new ArrayList<>()); | ||
for (int i = 0; i < edgeList.size(); i++) { | ||
Edge edge = edgeList.get(i); | ||
Info info = new Info(edge.num, edge.v, 0); | ||
info.set.add(info); | ||
pq.offer(info); | ||
} | ||
int res = -1; | ||
while (!pq.isEmpty()) { | ||
Info info = pq.poll(); | ||
|
||
if (info.v == dest) { | ||
res = info.cnt; | ||
break; | ||
} | ||
|
||
List<Edge> edges = adjMap.getOrDefault(info.v, new ArrayList<>()); | ||
for (int i = 0; i < edges.size(); i++) { | ||
Edge edge = edges.get(i); | ||
|
||
List<Edge> nexts = adjMap.getOrDefault(edge.u, new ArrayList<>()); | ||
Info next = new Info(edge.num, edge.u, info.cnt + ((edge.num == info.num) ? 0 : 1)); | ||
if (!info.set.add(next)) continue; | ||
next.set = new HashSet<>(info.set); | ||
pq.offer(next); | ||
for (int j = 0; j < nexts.size(); j++) { | ||
Edge nextEdge = nexts.get(j); | ||
next = new Info(nextEdge.num, nextEdge.v, next.cnt + ((nextEdge.num == next.num) ? 0 : 1)); | ||
Set<Info> set = new HashSet<>(info.set); | ||
if (set.add(next)) { | ||
next.set = set; | ||
pq.offer(next); | ||
} | ||
} | ||
} | ||
} | ||
return res; | ||
} | ||
} | ||
|
||
//이동 경로 정보 저장 | ||
class Info implements Comparable<Info> { | ||
int num; | ||
long v; | ||
int cnt; | ||
Set<Info> set = new HashSet<>(); //isv | ||
|
||
public Info(int num, long v, int cnt) { | ||
this.num = num; | ||
this.v = v; | ||
this.cnt = cnt; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Info info = (Info) o; | ||
return num == info.num && v == info.v; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(num, v); | ||
} | ||
|
||
@Override | ||
public int compareTo(Info o) { | ||
return Integer.compare(this.cnt, o.cnt); | ||
} | ||
} | ||
|
||
class Edge { | ||
int num; //호선 | ||
long v, u; //v -> u; | ||
|
||
public Edge(int num, long v, long u) { | ||
this.num = num; | ||
this.v = v; | ||
this.u = u; | ||
} | ||
} | ||
``` | ||
|
||
# 소요시간 | ||
|
||
1시간 30분 | ||
|
||
# 알고리즘 | ||
|
||
> 다익스트라, BFS | ||
|
||
# 풀이 | ||
|
||
# BOJ 16166 서울의 지하철 | ||
|
||
1. Map에 역번호, List<Edge> 형식으로 해당 역에서 갈 수 있는 모든 역 (다른 호선도 가능)을 저장 | ||
2. Edge는 호선, v -> u 의 정보 저장 | ||
3. Info는 호선, 역, 환승 횟수, isv역할의 Set<Info> 저장, 다익스트라를 사용하기 위해 환승 횟수를 기준으로 비교 | ||
4. 초기에 인접 역들을 양방향으로 Edge를 만들고 Map에 세팅해준다. | ||
5. 다익스트라 알고리즘을 통해 0번역에서 탐색 시작 | ||
6. HashSet을 통해 방문 여부를 확인하므로 equals, hashCode재정의 (호선, 역) | ||
7. 탐색 시 해당 (호선, 역)에서 갈 수 있는 인접 `역`을 먼저 탐색 후 해당 `역`의 다른 호선을 추가하는 방식으로 탐색 | ||
8. 같은 호선이라면 0 다른 호선이라면 1을 더해주어 환승 카운팅 | ||
9. 탐색 도중 목적지에 도착하면 res를 환승 횟수로 갱신하고 break; | ||
10. 최종적으로 res를 반환하여 출력 (res의 초기값은 -1으로 목적지 도달 불가 시 -1 반환) | ||
|
||
--- |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 이렇게 getOrDefault로 new 할당하는 방식은 새롭네요