AOJ_0212 Highway Express Bus
問題
解法
ダイクストラ法を使って、ああでもないこうでもないとやっている
うちになぜか解けてしまったのでよくわからない。
動的計画法も使っているような気がする…だけかもしれない。
割引券の枚数に対する最短距離?みたいなのを計算していく?というような?
ことをやっているのでは?ないでしょうか?
#include <cstdio> #include <queue> #include <algorithm> using namespace std; typedef pair<int, int> CP; //割引券の枚数と現在位置 typedef pair<int, CP> D; //最短距離とCP const int INF = 1 << 30; const int MAX_N = 100; int C, N, M, S, G; int rail[MAX_N][MAX_N]; int dijk(){ priority_queue<D> Q; //d[i][j] := jに残り割引券i枚以上で着いたときの最短距離 int d[C+1][N]; for(int i = 0; i <= C; i++) for(int j = 0; j < N; j++) d[i][j] = INF; Q.push(D(0, CP(C, S))); while(!Q.empty()){ D pos = Q.top(); Q.pop(); int dis = pos.first, cn = pos.second.first, p = pos.second.second; if(!(d[cn][p] > dis)) continue; //最短距離を更新 for(int i = 0; i <= cn; i++) d[i][p] = min(dis, d[i][p]); for(int i = 0; i < N; i++){ if(rail[i][p] == INF) continue; if(dis + rail[i][p] < d[cn][i]) Q.push(D(dis + rail[i][p], CP(cn, i))); if(cn != 0 && dis + rail[i][p]/2 < d[cn-1][i]) Q.push(D(dis + rail[i][p] / 2, CP(cn - 1, i))); } } int ans = INF; for(int i = 0; i <= C; i++) ans = min(ans, d[i][G]); return ans; } int main(){ while(scanf("%d %d %d %d %d", &C,&N,&M,&S,&G) && C){ for(int i = 0; i < N; i++) for(int j = 0; j < N; j++) rail[i][j] = INF; S--; G--; for(int i = 0; i < M; i++){ int a, b, f; scanf("%d %d %d", &a, &b, &f); a--; b--; rail[a][b] = f; rail[b][a] = f; } printf("%d\n", dijk()); } return 0; }