競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 271E

ABC271E

通る道の長さの最小を求める.最小の長さの合計ではない.

良いpath
良いpath とはどういうものかを考えると, \(E\) を先頭から見ていくことで判定できる. そこで \(E\) を基準に考える.
また,良いpath 自体は多くなりうるので,Dijikstra などで すべての良いpath を列挙するのは無理そうなので, そういう意味でも \(E\) を基準に考える.

Inplace DP (inline DP)
\(dp_{i,j} := \) \(E_{[0,j)}\) まで,last が \(i \in V\) minimam cost of good paths
とする. このままだと,時間計算量が \(O(NK)\).空間計算量は \(O(NK)\) or \(O(N+K)\).
遷移は少ない.\(j\) を固定すると,使う可能性がある辺は \(s_{j} \xrightarrow{j} t_{j}\) のみ. よって,inplace により時間計算量を \(O(N+K)\) に減らすことができた.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  ll n, m,k  ;
  cin >> n >> m >> k;

  vector<tuple<ll,ll,ll>> ed(m);
  rep(i,m){
    ll a,b,c; cin >> a >> b >> c;
    --a, --b;
    ed[i] = {c,a,b};
  }

  vll e(k);
  rep(i,k) {
    cin >> e[i]; --e[i];
  }

  // inplace なので,j in K の情報は不要.
  // 一つの配列を使いまわすのが inplace.
  vll dp(n, INFL);
  chmin(dp[0], 0LL);
  rep(i,k) {
    auto [c,a,b] = ed[e[i]];
    chmin(dp[b], c + dp[a]);
  }

  ll ans = dp[n-1];
  if(ans >= INFL) ans = -1;
  cout << ans << endl;

  return 0;
}