ABC 277

https://atcoder.jp/contests/abc277

A. ^{-1}

https://atcoder.jp/contests/abc277/tasks/abc277_a

B. Playing Cards Validation

https://atcoder.jp/contests/abc277/tasks/abc277_b

C. Ladder Takahashi

https://atcoder.jp/contests/abc277/tasks/abc277_c

D. Takahashi’s Solitaire

https://atcoder.jp/contests/abc277/tasks/abc277_d

E. Crystal Switches

https://atcoder.jp/contests/abc277/tasks/abc277_e

12 min で AC

類題: https://atcoder.jp/contests/abc395/tasks/abc395_e

$a_i = 0$ の辺で構成される sub graph を $G$, $a_i = 1$ の辺で構成される sub graph を $G^\prime$ とする。 このとき、辺 $(u, v)$ は $G^\prime$ 上では $(u+N, v+N)$ として扱う。 スイッチがある頂点 $x$ には頂点 $x+N$ との間にコスト 0 の辺を張り、それ以外の辺はコスト 1 としてダイクストラを実行する。 頂点 $N$, $2N$ のコストのうち最小を出力する。どちらの頂点にも到達できない場合は -1 を出力する。

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    ll N, M, K;
    cin >> N >> M >> K;

    vector<tuple<int, int, int>> es;
    rep(i, M) {
        int u, v, a;
        cin >> u >> v >> a;
        u--, v--;
        es.emplace_back(u, v, a);
    }

    vector<bool> sw(N);
    rep(i, K) {
        int s;
        cin >> s;
        s--;
        sw[s] = true;
    }

    vvint graph(N * 2);
    for (auto [u, v, a] : es) {
        if (a == 1) {
            graph[u].push_back(v);
            graph[v].push_back(u);
        } else {
            graph[u + N].push_back(v + N);
            graph[v + N].push_back(u + N);
        }
        if (sw[u]) {
            graph[u].push_back(u + N);
            graph[u + N].push_back(u);
        }
        if (sw[v]) {
            graph[v].push_back(v + N);
            graph[v + N].push_back(v);
        }
    }

    vll dists(N * 2, INF);
    dists[0] = 0;

    // cost, position
    deque<pair<ll, ll>> dq;
    dq.push_back({0, 0});
    while (dq.size()) {
        auto [cost, now] = dq.front();
        dq.pop_front();

        if (dists[now] < cost)
            continue;

        for (int nx : graph[now]) {
            ll d = cost;
            int add = 0;
            if (abs(nx - now) != N) {
                d++;
                add++;
            }
            if (dists[nx] <= d)
                continue;
            dists[nx] = d;
            if (add)
                dq.push_back({d, nx});
            else
                dq.push_front({d, nx});
        }
    }

    ll ans = INF;
    chmin(ans, dists[N - 1]);
    chmin(ans, dists[N * 2 - 1]);
    if (ans == INF)
        ans = -1;
    cout << ans << endl;
}

F. Sorting a Matrix

https://atcoder.jp/contests/abc277/tasks/abc277_f

G. Random Walk to Millionaire

https://atcoder.jp/contests/abc277/tasks/abc277_g

Ex. Constrained Sums

https://atcoder.jp/contests/abc277/tasks/abc277_h