AOJ 1318 - Long Distance Taxi
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1318
概要
自動車でガソリンを切らさずに出発地から目的地まで行きたい. その自動車は1リットルのガソリンで 10km 走ることができ,最大で cap リットルのガソリンを載せることができる.
N 本の距離 d[i] の道が街同士を双方向に結んでいる.
M 個の街にはガソリンスタンドがあり,そこでコスト無しで好きなだけ給油できる.
出発地から目的地までの最小の道程を答える.ただし,目的地まで行けない場合は -1 を答える.
制約
- 1 <= N <= 3000
- 1 <= M <= 300
- 1 <= cap <= 200
- 0 < d[i] <= 2000
解法
ガソリンスタンドのある街で最大まで給油できるため,cap リットルのガソリンで到達できる街同士にエッジを張ったグラフを M 回ダイクストラして作り,そのグラフの上で普通にダイクストラして最短経路を求める.
aoj/1318.cc1 #include <iostream> 2 #include <vector> 3 #include <map> 4 #include <queue> 5 using namespace std; 6 7 int main() 8 { 9 int N, M, C; 10 while (cin >> N >> M >> C && N != 0) { 11 C *= 10; 12 map<string,int> m; 13 string start, goal; 14 cin >> start >> goal; 15 m.insert(make_pair(start, 0)); 16 m.insert(make_pair(goal, 1)); 17 vector<vector<pair<int,int> > > gg(2); 18 for (int i = 0; i < N; i++) { 19 string src, dst; 20 int d; 21 cin >> src >> dst >> d; 22 int u, v; 23 if (!m.count(src)) { 24 u = m.size(); 25 m.insert(make_pair(src, u)); 26 gg.push_back(vector<pair<int,int> >()); 27 } else { 28 u = m[src]; 29 } 30 if (!m.count(dst)) { 31 v = m.size(); 32 m.insert(make_pair(dst, v)); 33 gg.push_back(vector<pair<int,int> >()); 34 } else { 35 v = m[dst]; 36 } 37 gg[u].push_back(make_pair(v, d)); 38 gg[v].push_back(make_pair(u, d)); 39 } 40 41 vector<int> gss, gss_map(gg.size(), -1); 42 gss.push_back(0); // start 43 gss.push_back(1); // goal 44 gss_map[0] = 0; 45 gss_map[1] = 1; 46 for (int i = 0; i < M; i++) { 47 string s; 48 cin >> s; 49 const int v = m[s]; 50 if (v != 0 && v != 1) { 51 gss_map[v] = gss.size(); 52 gss.push_back(v); 53 } 54 } 55 const int MM = gss.size(); 56 57 static const int INF = 10000000; 58 vector<vector<int> > dist(MM, vector<int>(MM, INF)); 59 for (int i = 0; i < MM; i++) { 60 priority_queue<pair<int,int> > q; 61 vector<int> dp(gg.size(), INF); 62 dp[gss[i]] = 0; 63 q.push(make_pair(0, gss[i])); 64 while (!q.empty()) { 65 const int n = q.top().second; 66 const int c = -q.top().first; 67 q.pop(); 68 if (c > dp[n]) { 69 continue; 70 } 71 for (vector<pair<int,int> >::const_iterator it = gg[n].begin(); it != gg[n].end(); ++it) { 72 int k = it->first; 73 const int cc = c + it->second; 74 if (cc <= C && cc < dp[k]) { 75 dp[k] = cc; 76 if (gss_map[k] != -1) { 77 dist[i][gss_map[k]] = min(dist[i][gss_map[k]], cc); 78 } else { 79 q.push(make_pair(-cc, k)); 80 } 81 } 82 } 83 } 84 } 85 86 priority_queue<pair<int,int> > q; 87 vector<int> dp(MM, INF); 88 dp[0] = 0; 89 q.push(make_pair(0, 0)); 90 while (!q.empty()) { 91 const int n = q.top().second; 92 const int c = -q.top().first; 93 q.pop(); 94 if (n == 1) { 95 cout << c << endl; 96 goto NEXT; 97 } 98 for (int v = 0; v < MM; v++) { 99 const int cc = c + dist[n][v]; 100 if (dist[n][v] != INF && cc < dp[v]) { 101 dp[v] = cc; 102 q.push(make_pair(-cc, v)); 103 } 104 } 105 } 106 cout << "-1" << endl; 107 NEXT: 108 ; 109 } 110 return 0; 111 }