- ダイクストラ法の練習問題として適しています
- 入力がやや厄介かもしれません
typedef complex<double> P;
bool input(P& p) {
double x, y;
if (!(cin >> x >> y)) {
return false;
}
p = P(x, y);
return true;
}
int main() {
vector<P> positions;
P p;
input(p);
positions.push_back(p);
input(p);
positions.push_back(p);
vector<vector<int> > subways;
vector<int> subway;
while (input(p)) {
if (p.real() < 0) {
subways.push_back(subway);
subway.clear();
} else {
subway.push_back(positions.size());
positions.push_back(p);
}
}
const int n = positions.size();
vector<vector<double> > g(n, vector<double>(n, 1e10));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
const double r = abs(positions[i] - positions[j]);
const double t = r / (10.0 * 1000.0 / 60.0);
g[i][j] = min(g[i][j], t);
}
}
for (vector<vector<int> >::iterator it = subways.begin(); it != subways.end(); ++it) {
const vector<int>& subway = *it;
const int m = subway.size();
for (int i = 0; i + 1 < m; ++i) {
const int from = subway[i];
const int to = subway[i + 1];
const double r = abs(positions[from] - positions[to]);
const double t = r / (40.0 * 1000.0 / 60.0);
g[from][to] = min(g[from][to], t);
g[to][from] = min(g[to][from], t);
}
}
vector<double> dp(n, 1e10);
dp[0] = 0;
priority_queue<pair<double, int> > q;
q.push(make_pair(0, 0));
while (!q.empty()) {
const double currentCost = -q.top().first;
const int currentNode = q.top().second;
q.pop();
if (abs(dp[currentNode] - currentCost) > EPS) {
continue;
}
for (int nextNode = 0; nextNode < n; ++nextNode) {
const double nextCost = currentCost + g[currentNode][nextNode];
if (dp[nextNode] > nextCost + EPS) {
dp[nextNode] = nextCost + EPS;
q.push(make_pair(-dp[nextNode], nextNode));
}
}
}
cout << (int)(dp[1] + 0.5) << endl;
}