Skip to content

Commit 15188ae

Browse files
authored
Merge pull request #707 from AlgorithmWithGod/lkhyun
[20250821] B형 / SWEA / 전기차여행 / 이강현
2 parents 61d79bb + dab09dd commit 15188ae

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
```java
2+
import java.util.*;
3+
class UserSolution {
4+
static class Edge implements Comparable<Edge>{
5+
int from;
6+
int to;
7+
int id;
8+
int time;
9+
int power;
10+
11+
Edge(int from, int to, int id, int time, int power){
12+
this.from = from;
13+
this.to = to;
14+
this.id = id;
15+
this.time = time;
16+
this.power = power;
17+
}
18+
19+
@Override
20+
public int compareTo(Edge other){
21+
return this.time - other.time;
22+
}
23+
}
24+
static class State implements Comparable<State>{
25+
// to로 오는데 걸린 시간과 남은 차량의 충전 용량
26+
int to;
27+
int time;
28+
int power;
29+
30+
State(int to, int time, int power){
31+
this.to = to;
32+
this.time = time;
33+
this.power = power;
34+
}
35+
36+
@Override
37+
public int compareTo(State other){
38+
if(this.time == other.time){
39+
return other.power - this.power;
40+
}else{
41+
return this.time - other.time;
42+
}
43+
}
44+
}
45+
static List<Edge>[] adjList;
46+
static int[] chargeOfCity;
47+
static Map<Integer,Edge> edgeById;
48+
49+
public void init(int N, int mCharge[], int K, int mId[], int sCity[], int eCity[], int mTime[], int mPower[]) {
50+
adjList = new ArrayList[N];
51+
chargeOfCity = new int[N];
52+
edgeById = new HashMap<>();
53+
54+
for (int i = 0; i < N; i++) {
55+
adjList[i] = new ArrayList<>();
56+
chargeOfCity[i] = mCharge[i];
57+
}
58+
59+
for (int i = 0; i < K; i++) {
60+
Edge e = new Edge(sCity[i], eCity[i], mId[i], mTime[i], mPower[i]);
61+
adjList[sCity[i]].add(e);
62+
edgeById.put(mId[i],e);
63+
}
64+
return;
65+
}
66+
67+
public void add(int mId, int sCity, int eCity, int mTime, int mPower) {
68+
Edge e = new Edge(sCity, eCity, mId, mTime, mPower);
69+
adjList[sCity].add(e);
70+
edgeById.put(mId,e);
71+
return;
72+
}
73+
74+
public void remove(int mId) {
75+
Edge e = edgeById.get(mId);
76+
adjList[e.from].remove(e);
77+
edgeById.remove(mId);
78+
return;
79+
}
80+
81+
public int[][] dijkstraForCar(int start, int end, int B, int[] corona){
82+
int[][] dist = new int[adjList.length][B+1]; //여기로 오는데 B만큼 충전량이 남음.
83+
PriorityQueue<State> pq = new PriorityQueue<>();
84+
for (int i = 0; i < dist.length; i++) {
85+
for (int j = 0; j <= B; j++) {
86+
dist[i][j] = Integer.MAX_VALUE;
87+
}
88+
}
89+
State init = new State(start, 0, B);
90+
dist[start][B] = 0;
91+
pq.offer(init);
92+
93+
while(!pq.isEmpty()){
94+
State cur = pq.poll();
95+
96+
if(dist[cur.to][cur.power] < cur.time) continue;
97+
if(cur.to == end) return dist;
98+
99+
for(Edge e : adjList[cur.to]){
100+
if(e.power > B) continue;
101+
int tempPower = cur.power;
102+
int tempTime = cur.time;
103+
while(tempPower < e.power){ //도착지로 가기위한 전기가 충분치 않아서 충전
104+
tempPower = Math.min(B,tempPower + chargeOfCity[cur.to]);
105+
tempTime++;
106+
}
107+
//딱 최소 용량만 충전하고 갔을때, 전염병 만나는지 혹은 기존의 최적 루트보다 최적인지 판단.
108+
if(corona[e.to] <= (tempTime + e.time) || dist[e.to][tempPower - e.power] <= (tempTime + e.time)) continue;
109+
pq.offer(new State(e.to, tempTime + e.time, tempPower - e.power));
110+
dist[e.to][tempPower - e.power] = tempTime + e.time;
111+
112+
while(tempPower != B){ //여기서 충전을 충분히 해두는게 이득일 수 있음
113+
tempPower = Math.min(B,tempPower + chargeOfCity[cur.to]);
114+
tempTime++;
115+
if(corona[e.to] <= (tempTime + e.time) || dist[e.to][tempPower - e.power] <= (tempTime + e.time)){
116+
continue;
117+
}
118+
pq.offer(new State(e.to, tempTime + e.time, tempPower - e.power));
119+
dist[e.to][tempPower - e.power] = tempTime + e.time;
120+
}
121+
}
122+
}
123+
return dist;
124+
}
125+
public int[] dijkstraForCorona(int start, int startTime){
126+
int[] dist = new int[adjList.length];
127+
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> a[1] - b[1]);
128+
for (int i = 0; i < dist.length; i++) {
129+
dist[i] = Integer.MAX_VALUE;
130+
}
131+
dist[start] = startTime;
132+
pq.offer(new int[]{start,startTime});
133+
134+
while(!pq.isEmpty()){
135+
int[] cur = pq.poll();
136+
137+
if(dist[cur[0]] < cur[1]) continue;
138+
139+
for(Edge e : adjList[cur[0]]){
140+
int newDist = cur[1] + e.time;
141+
if(newDist < dist[e.to]){
142+
pq.offer(new int[]{e.to,newDist});
143+
dist[e.to] = newDist;
144+
}
145+
}
146+
}
147+
return dist;
148+
}
149+
150+
public int cost(int B, int sCity, int eCity, int M, int mCity[], int mTime[]) {
151+
//전염병을 하나만 만나도 어차피 못감.
152+
//그니까 전염병들도 다익스트라를 돌려서 가장 빠르게 도시에 가는 경우를 미리 뽑아둠.
153+
int[][] coronas = new int[M][adjList.length];
154+
int[] minimumAccess = new int[adjList.length];
155+
for (int i = 0; i < M; i++) {
156+
coronas[i] = dijkstraForCorona(mCity[i],mTime[i]);
157+
}
158+
for (int i = 0; i < adjList.length; i++) {
159+
int minimum = coronas[0][i];
160+
for (int j = 1; j < M; j++) {
161+
minimum = Math.min(minimum,coronas[j][i]);
162+
}
163+
minimumAccess[i] = minimum;
164+
}
165+
166+
int result[][] = dijkstraForCar(sCity, eCity, B, minimumAccess);
167+
int ans = result[eCity][0];
168+
for (int i = 0; i <= B; i++) {
169+
ans = Math.min(ans, result[eCity][i]);
170+
}
171+
return ans == Integer.MAX_VALUE ? -1 : ans;
172+
}
173+
}
174+
```

0 commit comments

Comments
 (0)