Codeforces 187 B. AlgoRace
問題
n個の都市があり、m種類の車を使ったときの、
それぞれの都市aから都市bへ移動するのにかかる時間が与えられる。
このとき、以下のクエリr個に答えよ。
都市s[i]から都市t[i]へ、車の交換回数t[i]回以下で移動するときにかかる最小の時間。
ただし、車は好きな都市で、時間0で、好きな車に乗り換えられるものとする。
制約条件
n≦60
m≦60
r≦10^5
方針
都市iから都市jへ、乗り換え回数k回で移動するのにかかる最小時間をdp[i][j][k]とする。
すると、dp[i][j][k]は、dp[i][j][k-1]に、どこかで一回乗り換えが加わったものであるから、
dp[i][j][k] = min{dp[i][x][k-1] + dp[x][j][0] | xはどこかの都市}と書ける。
この漸化式にしたがってDPを最初にしておけば、各クエリに対してO(1)時間で答えることができる。
ソースコード
int n, m, r; int d[60][60][60], dp[60][60][61]; void run() { cin >> n >> m >> r; rep(l, m){ rep(i, n) rep(j, n) cin >> d[l][i][j]; rep(k, n) rep(i, n) rep(j, n) d[l][i][j] = min(d[l][i][j], d[l][i][k] + d[l][k][j]); } rep(k, 61) rep(i, n) rep(j, n) dp[i][j][k] = inf; rep(i, n) rep(j, n){ rep(k, m) dp[i][j][0] = min(dp[i][j][0], d[k][i][j]); } rep(i, 60) rep(a, n) rep(b, n){ rep(c, n) dp[a][b][i + 1] = min(dp[a][b][i + 1], dp[a][c][i] + dp[c][b][0]); } rep(i, r){ int a, b, t; cin >> a >> b >> t; t = min(t, 60); cout << dp[a-1][b-1][t] << endl; } }