-
Notifications
You must be signed in to change notification settings - Fork 17
/
(hard) TAN Network.js
76 lines (68 loc) · 2.14 KB
/
(hard) TAN Network.js
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* TAN Network
* https://www.codingame.com/training/hard/tan-network
* Statement:
* Given a list of train stations, their locations and connections, a
* starting point, and a final point, determine the names of the stations
* from the start to the end, based on the shortest path.
* Story:
* "Yeah, sure. Wait... Gonna have to call you back, I'm entering the
* subway.... No, not the sandwich thing, the... Oh come on.... Yeah, I'll
* meet you at the museum. No, the one next to the plaza where we had a
* coffee last week. Take the tramway line 6. Yeah. Right. Bye."
*/
const findStop = id => route.find(n => n.id === id);
const trip = {
startPoint: readline(),
endPoint: readline()
};
const route = [];
let N = +readline();
while(N--) {
const [id, name, , lat, lng] = readline().split`,`;
route.push({
id: id,
name: name.substr(1, name.length - 2),
lat: +lat * Math.PI / 180,
lng: +lng * Math.PI / 180,
links: [],
weight: Infinity,
previous: null
});
}
let M = +readline();
while(M--) {
const [startId, endId] = readline().split` `;
findStop(startId).links.push(route.findIndex(n => n.id === endId));
}
trip.startPoint = findStop(trip.startPoint);
trip.endPoint = findStop(trip.endPoint);
const DijkstraPath = (start, end) => {
const closed = route.concat();
start.weight = 0;
while(closed.length > 0) {
const next = closed.reduce((min, stop) => stop.weight < min.weight ? stop : min);
closed.splice(closed.indexOf(next), 1);
next.links.forEach(i => {
const current = route[i];
const weight = next.weight + Math.sqrt(
Math.pow((current.lng - next.lng) * Math.cos((next.lat + current.lat) / 2), 2)
+ Math.pow(current.lat - next.lat, 2)
) * 6371
if (current.weight > weight) {
current.weight = weight;
current.previous = next;
}
});
}
const result = [];
for (let stop = end; stop; stop = stop.previous) {
result.unshift(stop);
}
return result;
};
const path = DijkstraPath(trip.startPoint, trip.endPoint);
print(trip.endPoint.weight === Infinity
? 'IMPOSSIBLE'
: path.map(s => s.name).join('\n')
);