ABC 394

E - Palindromic Shortest Path

https://atcoder.jp/contests/abc394/tasks/abc394_e

解説 AC

短い回分から両端に同じ文字を追加していくことで回分の長さを増やしていく。

void solve() {
    int n;
    cin >> n;
    vector<string> delta(n);
    rep(i, n) cin >> delta[i];

    vvll dist(n, vll(n, -1));
    // 回分の最短距離が決まっている path を que に入れる
    queue<pair<int, int>> que;

    rep(i, n) {
        dist[i][i] = 0;
        que.push({i, i});
    }

    rep(i, n) rep(j, n) {
        if (i != j && delta[i][j] != '-') {
            dist[i][j] = 1;
            que.push({i, j});
        }
    }

    while (que.size()) {
        auto [i, j] = que.front();
        que.pop();

        rep(k, n) {
            rep(l, n) {
                if (delta[k][i] != '-' && delta[k][i] == delta[j][l] &&
                    dist[k][l] == -1) {
                    // i -> j への path の回分の長さはすでに決まっている
                    // delta[k][i] == delta[j][l] ならば、k -> i -> j -> l という path が回分になる
                    // que には距離が短い順に入っているので一番最初に見つかった k -> l の path を最短として良い
                    // k -> i -> j -> l なる path を考えるときに (i,j) の全ての組み合わせを調べる必要はないということ
                    dist[k][l] = dist[i][j] + 2;
                    que.push({k, l});
                }
            }
        }
    }

    for (auto v : dist)
        print(v);
}