Problem:
E : Arojam's Mask / 仮面

問題文

あなたは勇者である。勇者が旅をしている世界は N 個の街と、異なる街同士を結ぶ M 本の道からなる。道 i は街 a_i と街 b_i を結び、双方向に移動可能である。

街 S から出発し、街 T に移動することが勇者の目的である。 S,T は異なる街である。勇者は 0 日目に街を出発し、ちょうど 1 日かけて 1 本の道を通って移動することができる。道を使った移動には日数の制限 R があり、R 日目を超えることはできない。

また、勇者は任意の街で「オカリナを吹く」こともできる。オカリナを吹くと、時は 0 日目に、位置は街 S に戻される。つまり、R 回を超える移動を行う場合は、最低一度はオカリナを吹かなければならない。

さらに、勇者がある街に位置すると「イベント」が発生することがある。イベントは E 種類あり、i 番目のイベントは、街 c_{i} で発生する。イベントは勇者がそこにいると自動的に発生し、新たに道 a’_i と b’_i を結ぶ道が生じる。この道はオカリナを吹いても消えることはなく、初めから存在する道とも、別のイベントによって追加される道とも重複しない。ある町で起こるイベントは高々1つである。

さて、勇者の今日の仕事は、街 T に到達するまでに必要な移動の回数とオカリナを吹く回数の和の最小値を求めるプログラムを書くことである。

入力

入力は以下の形式で与えられる。

N M E S T R
a_{0} b_{0}
…
a_{M−1} b_{M−1}
a’_{0} b’_{0} c_{0}
…
a’_{E−1} b’_{E−1} c_{E−1}

制約

入力はすべて整数である

2 \≤ N \≤ 100

1 \≤ M+E \≤ N(N−1)/2

0 \≤ E \≤ 4

0 \≤ R \≤ 100

0 \≤ S,T,a_i,b_i,a’_i,b’_i,c_i \≤ N−1

S ≠ T

a_{i} ≠ b_{i}, a’_{i} ≠ b’_{i}

a_{i} と b_{i}、a’_{i} と b’_{i}の全ての組は重複しない

i ≠ j なら c_{i} ≠ c_{j}

出力

答えを一行で出力せよ。どうしても T へ到達できない場合は −1 を出力せよ。

サンプル

サンプル入力1

8 5 2 0 5 5
0 1
0 3
0 6
1 2
6 7
3 4 7
4 5 2

サンプル出力1

9

例えば以下のように移動すればよい。イベントを起こすまでは道(4,5), (3,4)は存在しないことに注意せよ。

街2に行くと4から5へ移動できるようになる

オカリナを使用し0へ戻る

街7に行くと3から4へ移動できるようになる

オカリナを使用し0へ戻る

0から5へまっすぐ進む

サンプル入力2

7 5 1 0 6 8
0 1
1 2
2 3
3 4
4 5
3 6 5

サンプル出力2

8

オカリナを1度も吹かない経路が最適である。

サンプル入力3

4 1 4 1 2 3
3 1
3 2 0
0 1 3
0 3 1
0 2 2

サンプル出力3

5

街 S でイベントが起こることもある。

Solution in C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

// template {{{
#define  range(i, l, r) for (int i = (int)(l); i < (int)(r); (i) += 1)
#define rrange(i, l, r) for (int i = (int)(r) - 1; i >= (int)(l); (i) -= 1)

#define  whole(f, x, ...) ([&](decltype((x)) container) { return (f)(  begin(container),  end(container), ## __VA_ARGS__); })(x)
#define rwhole(f, x, ...) ([&](decltype((x)) container) { return (f)( rbegin(container), rend(container), ## __VA_ARGS__); })(x)

#define debug(x) cerr << "(" << __LINE__ << ")" << #x << ": " << (x) << endl

using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;

// constexpr i32 mod   = 998244353;
constexpr i32 mod   = 1e9 + 7;
constexpr i32 inf   = 1001001001;
constexpr i64 infll = 1001001001001001001ll;

constexpr int dx[] = {0, -1, 1, 0, -1, 1, -1, 1};
constexpr int dy[] = {-1, 0, 0, 1, -1, -1, 1, 1};

struct IoSetup { IoSetup(int x = 15){ cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(x); cerr << fixed << setprecision(x); } } iosetup;

template <typename T = i64> T input() { T x; cin >> x; return x; }

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) { range(i, 0, v.size()) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; }
template <typename T> istream &operator>>(istream &is, vector<T> &v) { for (T &in : v) is >> in; return is; }

template <typename T1, typename T2> ostream &operator<<(ostream &os, pair<T1, T2> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
template <typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &p) { is >> p.first >> p.second; return is; }

template <typename T> vector<T> make_vector(size_t a, T b) { return vector<T>(a, b); }
template <typename... Ts> auto make_vector(size_t a, Ts... ts) { return vector<decltype(make_vector(ts...))>(a, make_vector(ts...)); }

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }
// }}}

void solver() {
    int n, m, e, s, t, r;
    cin >> n >> m >> e >> s >> t >> r;

    auto G = make_vector(n, 0, 0);
    range(i, 0, m) {
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }

    vector< int > as(e), bs(e), cs(e);
    range(i, 0, e) {
        cin >> as[i] >> bs[i] >> cs[i];
    }

    struct type {
        int dist, cnt, bit, day, v;
        type(int dist, int cnt, int bit, int day, int v) : dist(dist), cnt(cnt), bit(bit), day(day), v(v) {}
    };

    auto cmp = [](const type a, const type b) {
        return a.dist > b.dist;
    };

    priority_queue< type, vector< type >, decltype(cmp) > pq{cmp};
    int sbit = 0;
    range(i, 0, e) {
        if (cs[i] == s) sbit = sbit | (1 << i);
    }
    pq.emplace(0, 0, sbit, 0, s);
    auto d = make_vector(5, 1 << e, r + 1, n, inf);
    d[0][sbit][0][s] = 0;

    while (!pq.empty()) {
        auto p = pq.top();
        pq.pop();

        int cnt = p.cnt;
        int bit = p.bit;
        int day = p.day;
        int v = p.v;

        if (p.dist > d[cnt][bit][day][v]) continue;

        if (cnt < 4 && chmin(d[cnt + 1][bit][0][s], d[cnt][bit][day][v] + 1)) {
            pq.emplace(d[cnt + 1][bit][0][s], cnt + 1, bit, 0, s);
        }

        if (day == r) continue;
            
        for (auto u: G[v]) {
            int nbit = bit;
            range(i, 0, e) {
                if (u == cs[i]) nbit = nbit | (1 << i);
            }

            if (chmin(d[cnt][nbit][day + 1][u], d[cnt][bit][day][v] + 1)) {
                pq.emplace(p.dist + 1, cnt, nbit, day + 1, u);
            }
        }

        range(i, 0, e) {
            if ((bit & (1 << i)) == 0) continue;
            if (as[i] == v) {
                int nbit = bit;
                range(j, 0, e) {
                    if (bs[i] == cs[j]) nbit = nbit | (1 << j);
                }
                if (chmin(d[cnt][nbit][day + 1][bs[i]], p.dist + 1)) {
                    pq.emplace(p.dist + 1, cnt, nbit, day + 1, bs[i]);
                }
            }
            if (bs[i] == v) {
                int nbit = bit;
                range(j, 0, e) {
                    if (as[i] == cs[j]) nbit = nbit | (1 << j);
                }
                if (chmin(d[cnt][nbit][day + 1][as[i]], p.dist + 1)) {
                    pq.emplace(p.dist + 1, cnt, nbit, day + 1, as[i]);
                }
            }
        }

    }

    int ans = inf;
    range(cnt, 0, 5) range(bit, 0, (1 << e)) range(day, 0, r + 1) {
        chmin(ans, d[cnt][bit][day][t]);
    }

    if (ans == inf) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }
}

signed main(int argc, char *argv[]) {
    solver();
}