ABC 277
Table of Contents
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