Problem:
パレード
JOI 王国では，JOIG の開催を記念して鼓笛隊のパレードを行うことになった．
JOI 王国には
N
個の都市があり，
1
から
N
までの番号が付けられている．また，鼓笛隊が通行可能な一方通行の道が
M
本あり，
1
から
M
までの番号が付けられている．道
i
(
1 ≦ i ≦ M
) は都市
A
i
から都市
B
i
へ向かう一方通行の道であり，長さは
C
i
である．
パレードでは，鼓笛隊は次の条件を満たすように移動しなければならない．
都市
1
を出発し，何本かの道を進行方向に進むことを繰り返して都市
N
へ向かう．
鼓笛隊が通る道の長さの総和は
L
以下である．
JOI 王国の女王であるあなたは，この条件を満たす鼓笛隊の移動経路が無いかもしれないことに気が付いた．そこで，パレードを行うために，パレード当日に
0
本以上の道の進行方向を反転させることにした．
混乱を避けるため，なるべく進行方向を反転させる道の本数は少なくしたい．
JOI 王国の都市と道の情報と，整数
L
が与えられたとき，いくつかの道の進行方向を反転させることでパレードを行うことができるかを判定し，もし行うことができる場合はパレードを行うために必要な進行方向を反転させる道の本数の最小値を出力せよ．
制約
2 ≦ N ≦ 1000
．
0 ≦ M ≦ 1000
．
1 ≦ L ≦ 1000000000
．
1 ≦ A
i
≦ N
(
1 ≦ i ≦ M
)．
1 ≦ B
i
≦ N
(
1 ≦ i ≦ M
)．
A
i
≠ B
i
(
1 ≦ i ≦ M
)．
(A
i
, B
i
) ≠ (A
j
, B
j
)
(
1 ≦ i < j ≦ M
)．
1 ≦ C
i
≦ 1000000
(
1 ≦ i ≦ M
)．
入力される値はすべて整数である．
入力
入力は以下の形式で標準入力から与えられる．
N
M
L
A
1
B
1
C
1
A
2
B
2
C
2
:
A
M
B
M
C
M
出力
標準出力に，パレードを行うために必要な進行方向を反転させる道の本数の最小値を
1
行で出力せよ．ただし，どのように道の進行方向を反転させてもパレードを行うことができない場合は，
-1
を出力せよ．
入出力例
入力例 1
3 2 5
2 1 2
2 3 3
出力例 1
1
道
1
の進行方向を反転させると，パレードを行うことができる．
これが最小値であるため，
1
を出力する．
入力例 2
3 1 10
2 1 5
出力例 2
-1
どのように道の進行方向を反転させてもパレードを行うことができないため，
-1
を出力する．
入力例 3
4 8 11
3 1 6
1 3 6
2 4 3
4 2 3
4 3 6
3 4 6
2 1 5
1 2 5
出力例 3
0
入力例 4
5 6 1000000000
5 2 1
2 3 1
3 4 1
4 2 1
2 1 1
1 3 1
出力例 4
1
入力例 5
6 15 777777
1 3 497295
4 1 422722
4 5 607164
2 3 135688
5 2 995652
5 1 670296
3 1 138860
4 6 736614
6 3 620085
2 1 796353
6 4 949756
4 2 750680
6 5 591550
5 3 229431
3 2 668173
出力例 5
2
情報オリンピック日本委員会
作 『日本情報オリンピック 第1回 女性部門』

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N_MAX=1000;

struct edge{
	int to,cost;
};

struct S{
	int node,rcnt,dist;
	bool operator<(const S &x)const{
		return x.dist<dist;
	}
};

int N,M,L,D[N_MAX][N_MAX+1];
vector<edge>E[N_MAX],R[N_MAX];
priority_queue<S>pq;

int main(){
	cin>>N>>M>>L;
	for(int i=0;i<M;i++){
		int A,B,C;
		cin>>A>>B>>C;
		A--;
		B--;
		E[A].push_back({B,C});
		R[B].push_back({A,C});
	}
	for(int i=0;i<N;i++){
		for(int j=0;j<=N;j++){
			D[i][j]=-1;
		}
	}
	pq.push({0,0,0});
	while(!pq.empty()){
		S s=pq.top();
		pq.pop();
		if(D[s.node][s.rcnt]==-1&&s.dist<=L){
			D[s.node][s.rcnt]=s.dist;
			for(edge e:E[s.node]){
				pq.push({e.to,s.rcnt,s.dist+e.cost});
			}
			if(s.rcnt<N){
				for(edge e:R[s.node]){
					pq.push({e.to,s.rcnt+1,s.dist+e.cost});
				}
			}
		}
	}
	for(int i=0;i<N;i++){
		if(D[N-1][i]!=-1){
			cout<<i<<endl;
			return 0;
		}
	}
	cout<<-1<<endl;
	return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 33140
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (ll i = 0; i < (ll) (n); i++)
template<class T>
bool chmin(T& p, T q, bool C = 1) {
    if (C == 0 && p == q) {
        return 1;
    }
    if (p > q) {
        p = q;
        return 1;
    }
    else {
        return 0;
    }
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);
   
    ll N,M,L;
    cin>>N>>M>>L;
    vector<vector<pair<ll,ll>>> G(N);
    vector<vector<pair<ll,ll>>> IG(N);
    rep(i,M){
        ll U,V,C;
        cin>>U>>V>>C;
        U--;V--;
        G[U].push_back({V,C});
        IG[V].push_back({U,C});
    }
    vvll dist(N,vll(M+1,1e18));
    dist[0][0]=0;
    priority_queue<pair<pair<ll,ll>,ll>,vector<pair<pair<ll,ll>,ll>>,greater<pair<pair<ll,ll>,ll>>> Q;
    Q.push({{0,0},0});
    vector<vector<bool>> seen(N,vector<bool>(M+1,0));
    while(!Q.empty()){
        auto b=Q.top();
        Q.pop();
        ll d=b.first.first;
        ll f=b.first.second;
        ll n=b.second;
        if(seen[n][f])continue;
        seen[n][f]=1;
        for(auto vw:G[n]){
            ll v=vw.first;
            ll w=vw.second;
            if(seen[v][f])continue;
            if(dist[v][f]<=d+w)continue;
            dist[v][f]=d+w;
            Q.push({{d+w,f},v});
        }
        if(f==M)continue;
        for(auto vw:IG[n]){
            ll v=vw.first;
            ll w=vw.second;
            if(seen[v][f+1])continue;
            if(dist[v][f+1]<=d+w)continue;
            dist[v][f+1]=d+w;
            Q.push({{d+w,f+1},v});
        }
    }
    ll an=1e18;
    rep(i,M+1){
        if(dist[N-1][i]<=L)chmin(an,i);
    }
    cout<<(an<1e17?an:-1)<<endl;
}
accuracy: 1
time_ms: 160
memory_kb: 19024
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <climits>

using namespace std;

struct Edge {
    int to, length;
};

struct State {
    int node, distance, reversed;
    bool operator>(const State &other) const {
        return distance > other.distance;
    }
};

int N, M, L;
vector<vector<Edge> > graph; // 注意這裡的空格
vector<vector<Edge> > reverse_graph; // 注意這裡的空格

int dijkstra(int max_reversals) {
    priority_queue<State, vector<State>, greater<State> > pq; // 注意這裡的空格
    vector<vector<int> > dist(N + 1, vector<int>(max_reversals + 1, INT_MAX)); // 注意這裡的空格
    pq.push((State){1, 0, 0});
    dist[1][0] = 0;

    while (!pq.empty()) {
        State state = pq.top();
        pq.pop();

        if (state.node == N && state.distance <= L) {
            return state.reversed;
        }

        if (state.distance > L) {
            continue;
        }

        for (size_t i = 0; i < graph[state.node].size(); ++i) {
            const Edge &edge = graph[state.node][i];
            int next_node = edge.to;
            int next_dist = state.distance + edge.length;

            if (next_dist < dist[next_node][state.reversed]) {
                dist[next_node][state.reversed] = next_dist;
                pq.push((State){next_node, next_dist, state.reversed});
            }
        }

        if (state.reversed < max_reversals) {
            for (size_t i = 0; i < reverse_graph[state.node].size(); ++i) {
                const Edge &edge = reverse_graph[state.node][i];
                int next_node = edge.to;
                int next_dist = state.distance + edge.length;

                if (next_dist < dist[next_node][state.reversed + 1]) {
                    dist[next_node][state.reversed + 1] = next_dist;
                    pq.push((State){next_node, next_dist, state.reversed + 1});
                }
            }
        }
    }

    return -1;
}

int main() {
    cin >> N >> M >> L;
    graph.resize(N + 1);
    reverse_graph.resize(N + 1);

    for (int i = 0; i < M; ++i) {
        int A, B, C;
        cin >> A >> B >> C;
        graph[A].push_back((Edge){B, C});
        reverse_graph[B].push_back((Edge){A, C});
    }

    int left = 0, right = N;
    int result = -1;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (dijkstra(mid) != -1) {
            result = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }

    cout << result << endl;

    return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 8612
final_rank: 8

code_snippet: #line 1 "/opt/library/template.hpp"
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'001'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;
#define inf infty<ll>

using pi = pair<ll, ll>;
using vi = vector<ll>;
using vvi = vector<vector<ll>>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

#define rep1(a) for (ll _ = 0; _ < (ll)(a); ++_)
#define rep2(i, a) for (ll i = 0; i < (ll)(a); ++i)
#define rep3(i, a, b) for (ll i = a; i < (ll)(b); ++i)
#define rep4(i, a, b, c) for (ll i = a; i < (ll)(b); i += (c))
#define rrep1(a) for (ll i = (a)-1; i >= (ll)(0); --i)
#define rrep2(i, a) for (ll i = (a)-1; i >= (ll)(0); --i)
#define rrep3(i, a, b) for (ll i = (b)-1; i >= (ll)(a); --i)
#define rrep4(i, a, b, c) for (ll i = (b)-1; i >= (ll)(a); i -= (c))
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep(...) overload4(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)

#define all(x) (x).begin(),(x).end()
#define len(x) (ll)(x.size())
#define elif else if
#define bit(x, i) (((x)>>(i))&1)

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll
#define abs llabs

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

ll popcnt(ll x) { return __builtin_popcountll(x); }
ll popcnt(u64 x) { return __builtin_popcountll(x); }
ll popcnt_mod_2(ll x) { return __builtin_parityll(x); }
ll popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
ll topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
ll topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
ll lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
ll lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template<typename T> T SUM(const vector<T> &A) {
  T s = 0; for (auto &&a: A) s += a;
  return s;
}

template <typename T>
T POP(queue<T> &que) {
  T a = que.front();
  que.pop();
  return a;
}
template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
f128 binary_search_real(F check, f128 ok, f128 ng, ll iter = 100) {
  rep(iter) {
    f128 x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  rep(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vc<T> cumsum(vc<U> &A, ll off = 1) {
  ll N = A.size();
  vc<T> B(N + 1);
  rep(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vi argsort(const vector<T> &A) {
  vi ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](ll i, ll j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vi &I) {
  vc<T> B(len(I));
  rep(i, len(I)) B[i] = A[I[i]];
  return B;
}

template<typename T> inline bool chmax(T &a, T b) {return ((a<b)?(a=b,true):(false));}
template<typename T> inline bool chmin(T &a, T b) {return ((a>b)?(a=b,true):(false));}

inline void wt(const char c) { cout << c; }
inline void wt(const string s) { cout << s; }
inline void wt(const char *s) { cout << s; }

template <typename T>
void wt_integer(T x) {
  if (x < 0) { cout << (i64)(x); }
  else { cout << (u64)(x); }
}
template <typename T>
void wt_real(T x) {
  cout << fixed << setprecision(15) << (long double)(x);
}

inline void wt(int x) { wt_integer(x); }
inline void wt(ll x) { wt_integer(x); }
inline void wt(i128 x) { wt_integer(x); }
inline void wt(u32 x) { wt_integer(x); }
inline void wt(u64 x) { wt_integer(x); }
inline void wt(u128 x) { wt_integer(x); }
inline void wt(double x) { wt_real(x); }
inline void wt(long double x) { wt_real(x); }
inline void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first); wt(' '); wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
void onez(bool t = 1) { print(t ? 1 : 0); }
#define endl '\n'
#define dump(x) {cerr << #x " = " << x << '\n';}
#line 2 "/opt/library/graph/base.hpp"

template <typename T>
struct Edge {
  ll frm, to;
  T cost;
  ll id;
};

template <typename T = ll, bool directed = false>
struct Graph {
  static constexpr bool is_directed = directed;
  ll N, M;
  using cost_type = T;
  using edge_type = Edge<T>;
  vector<edge_type> edges;
  vi indptr;
  vc<edge_type> csr_edges;
  vc<ll> vc_deg, vc_indeg, vc_outdeg;
  bool prepared;

  class OutgoingEdges {
  public:
    OutgoingEdges(const Graph* G, ll l, ll r) : G(G), l(l), r(r) {}

    const edge_type* begin() const {
      if (l == r) { return 0; }
      return &G->csr_edges[l];
    }

    const edge_type* end() const {
      if (l == r) { return 0; }
      return &G->csr_edges[r];
    }

  private:
    const Graph* G;
    ll l, r;
  };

  bool is_prepared() { return prepared; }

  Graph() : N(0), M(0), prepared(0) {}
  Graph(ll N) : N(N), M(0), prepared(0) {}

  void build(ll n) {
    N = n, M = 0;
    prepared = 0;
    edges.clear();
    indptr.clear();
    csr_edges.clear();
    vc_deg.clear();
    vc_indeg.clear();
    vc_outdeg.clear();
  }

  void add(ll frm, ll to, T cost = 1, ll i = -1) {
    assert(!prepared);
    assert(0 <= frm && 0 <= to && to < N);
    if (i == -1) i = M;
    auto e = edge_type({frm, to, cost, i});
    edges.eb(e);
    ++M;
  }

#ifdef FASTIO
  // wt, off
  void read_tree(bool wt = false, ll off = 1) { read_graph(N - 1, wt, off); }

  void read_graph(ll M, bool wt = false, ll off = 1) {
    for (ll m = 0; m < M; ++m) {
      LL(a, b);
      a -= off, b -= off;
      if (!wt) {
        add(a, b);
      } else {
        T c;
        read(c);
        add(a, b, c);
      }
    }
    build();
  }
#endif

  void build() {
    assert(!prepared);
    prepared = true;
    indptr.assign(N + 1, 0);
    for (auto&& e: edges) {
      indptr[e.frm + 1]++;
      if (!directed) indptr[e.to + 1]++;
    }
    for (ll v = 0; v < N; ++v) { indptr[v + 1] += indptr[v]; }
    auto counter = indptr;
    csr_edges.resize(indptr.back() + 1);
    for (auto&& e: edges) {
      csr_edges[counter[e.frm]++] = e;
      if (!directed)
        csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
    }
  }

  OutgoingEdges operator[](ll v) const {
    assert(prepared);
    return {this, indptr[v], indptr[v + 1]};
  }

  vi deg_array() {
    if (vc_deg.empty()) calc_deg();
    return vc_deg;
  }

  pair<vi, vi> deg_array_inout() {
    if (vc_indeg.empty()) calc_deg_inout();
    return {vc_indeg, vc_outdeg};
  }

  ll deg(ll v) {
    if (vc_deg.empty()) calc_deg();
    return vc_deg[v];
  }

  ll in_deg(ll v) {
    if (vc_indeg.empty()) calc_deg_inout();
    return vc_indeg[v];
  }

  ll out_deg(ll v) {
    if (vc_outdeg.empty()) calc_deg_inout();
    return vc_outdeg[v];
  }

#ifdef FASTIO
  void debug() {
    print("Graph");
    if (!prepared) {
      print("frm to cost id");
      for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
    } else {
      print("indptr", indptr);
      print("frm to cost id");
      rep(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
    }
  }
#endif

  vi new_idx;
  vc<bool> used_e;

  // G における頂点 V[i] が、新しいグラフで i になるようにする
  // {G, es}
  Graph<T, directed> rearrange(vi V, bool keep_eid = 0) {
    if (len(new_idx) != N) new_idx.assign(N, -1);
    if (len(used_e) != M) used_e.assign(M, 0);
    ll n = len(V);
    rep(i, n) new_idx[V[i]] = i;
    Graph<T, directed> G(n);
    vi history;
    rep(i, n) {
      for (auto&& e: (*this)[V[i]]) {
        if (used_e[e.id]) continue;
        ll a = e.frm, b = e.to;
        if (new_idx[a] != -1 && new_idx[b] != -1) {
          history.eb(e.id);
          used_e[e.id] = 1;
          ll eid = (keep_eid ? e.id : -1);
          G.add(new_idx[a], new_idx[b], e.cost, eid);
        }
      }
    }
    rep(i, n) new_idx[V[i]] = -1;
    for (auto&& eid: history) used_e[eid] = 0;
    G.build();
    return G;
  }

private:
  void calc_deg() {
    assert(vc_deg.empty());
    vc_deg.resize(N);
    for (auto&& e: edges) vc_deg[e.frm]++, vc_deg[e.to]++;
  }

  void calc_deg_inout() {
    assert(vc_indeg.empty());
    vc_indeg.resize(N);
    vc_outdeg.resize(N);
    for (auto&& e: edges) { vc_indeg[e.to]++, vc_outdeg[e.frm]++; }
  }
};
#line 3 "main.cpp"

int solve();
int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  while (!solve()) {break;}
  return 0;
}

struct S{
  ll node, rcnt, dist;
  bool operator<(const S &x) const {
    return x.dist < dist;
  }
};

int solve() {
  ll N, M, L, A, B, C;
  cin >> N >> M >> L;
  Graph<ll,true> G(N), GR(N);
  rep(M) {
    cin >> A >> B >> C;
    A--; B--;
    G.add(A, B, C);
    GR.add(B, A, C);
  }
  G.build(); GR.build();
  vv(ll, dp, N, N+1, -1);
  pq<S> Q;
  Q.push({0, 0, 0});
  while (!Q.empty()) {
    auto v = POP(Q);
    if ((dp[v.node][v.rcnt] == -1) and (v.dist <= L)) {
      dp[v.node][v.rcnt] = v.dist;
      for (auto e: G[v.node]) {
        Q.push({e.to, v.rcnt, v.dist+e.cost});
      }
      if (v.rcnt < N) {
        for (auto e: GR[v.node]) {
          Q.push({e.to, v.rcnt+1, v.dist+e.cost});
        }
      }
    }
  }
  rep(i, N) {
    if (dp[N-1][i] != -1) {
      print(i);
      return 0;
    }
  }
  print(-1);
  return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 62428
final_rank: 10

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/graph/graph.hpp"
#include <iostream>
#include <vector>

/**
 * @brief 重み付きグラフ
 *
 * @tparam T 辺の重みの型
 */
template <class T>
struct Graph {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to(), _weight() {}
        constexpr _edge(int from, int to, T weight) : _from(from), _to(to), _weight(weight) {}
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }

        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr T weight() const { return _weight; }

      private:
        int _from, _to;
        T _weight;
    };

  public:
    using edge_type = typename Graph<T>::_edge;

    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}

    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }

    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to, T weight = T(1)) { edges[from].emplace_back(from, to, weight); }
    void add_edges(int from, int to, T weight = T(1)) {
        edges[from].emplace_back(from, to, weight);
        edges[to].emplace_back(to, from, weight);
    }

    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edge(from - base, to - base, weight);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edges(from - base, to - base, weight);
        }
    }

  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};

template <>
struct Graph<void> {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to() {}
        constexpr _edge(int from, int to) : _from(from), _to(to) {}

        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr int weight() const { return 1; }
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }

      private:
        int _from, _to;
    };

  public:
    using edge_type = typename Graph<void>::_edge;

    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}

    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }

    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to) { edges[from].emplace_back(from, to); }
    void add_edges(int from, int to) {
        edges[from].emplace_back(from, to);
        edges[to].emplace_back(to, from);
    }

    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edge(from - base, to - base);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edges(from - base, to - base);
        }
    }

  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 4 "a.cpp"

int main(void) {
    int n, m;
    cin >> n >> m;
    ll l;
    cin >> l;
    Graph<pair<int, int>> g(n);
    rep (i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a, --b;
        g.add_edge(a, b, {0, c});
        g.add_edge(b, a, {1, c});
    }

    vector dp(n, vector(m + 1, INF));
    dp[0][0] = 0;
    priority_queue<tuple<ll, int, int>, vector<tuple<ll, int, int>>, greater<>> pq;
    pq.emplace(0, 0, 0);
    while (!pq.empty()) {
        auto [d, x, y] = pq.top();
        pq.pop();
        if (dp[x][y] != d)
            continue;
        for (auto e : g[x]) {
            auto [a, b] = e.weight();
            if (y + a <= m && chmin(dp[e.to()][y + a], d + b)) {
                pq.emplace(dp[e.to()][y + a], e.to(), y + a);
            }
        }
    }

    rep (i, m + 1) {
        if (dp[n - 1][i] <= l) {
            co(i);
            return 0;
        }
    }
    co(-1);

    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 16628
final_rank: 5

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/graph/graph.hpp"
#include <iostream>
#include <vector>

/**
 * @brief 重み付きグラフ
 *
 * @tparam T 辺の重みの型
 */
template <class T>
struct Graph {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to(), _weight() {}
        constexpr _edge(int from, int to, T weight) : _from(from), _to(to), _weight(weight) {}
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }

        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr T weight() const { return _weight; }

      private:
        int _from, _to;
        T _weight;
    };

  public:
    using edge_type = typename Graph<T>::_edge;

    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}

    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }

    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to, T weight = T(1)) { edges[from].emplace_back(from, to, weight); }
    void add_edges(int from, int to, T weight = T(1)) {
        edges[from].emplace_back(from, to, weight);
        edges[to].emplace_back(to, from, weight);
    }

    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edge(from - base, to - base, weight);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            T weight;
            std::cin >> from >> to >> weight;
            add_edges(from - base, to - base, weight);
        }
    }

  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};

template <>
struct Graph<void> {
  private:
    struct _edge {
        constexpr _edge() : _from(), _to() {}
        constexpr _edge(int from, int to) : _from(from), _to(to) {}

        constexpr int from() const { return _from; }
        constexpr int to() const { return _to; }
        constexpr int weight() const { return 1; }
        constexpr bool operator<(const _edge &rhs) const { return weight() < rhs.weight(); }
        constexpr bool operator>(const _edge &rhs) const { return rhs < *this; }

      private:
        int _from, _to;
    };

  public:
    using edge_type = typename Graph<void>::_edge;

    Graph() : _size(), edges() {}
    Graph(int v) : _size(v), edges(v) {}

    const auto &operator[](int i) const { return edges[i]; }
    auto &operator[](int i) { return edges[i]; }
    const auto begin() const { return edges.begin(); }
    auto begin() { return edges.begin(); }
    const auto end() const { return edges.end(); }
    auto end() { return edges.end(); }
    constexpr int size() const { return _size; }

    void add_edge(const edge_type &e) { edges[e.from()].emplace_back(e); }
    void add_edge(int from, int to) { edges[from].emplace_back(from, to); }
    void add_edges(int from, int to) {
        edges[from].emplace_back(from, to);
        edges[to].emplace_back(to, from);
    }

    void input_edge(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edge(from - base, to - base);
        }
    }
    void input_edges(int m, int base = 1) {
        for (int i = 0; i < m; ++i) {
            int from, to;
            std::cin >> from >> to;
            add_edges(from - base, to - base);
        }
    }

  private:
    int _size;
    std::vector<std::vector<edge_type>> edges;
};
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 4 "a.cpp"

int main(void) {
    int n, m;
    cin >> n >> m;
    ll l;
    cin >> l;
    Graph<pair<int, int>> g(n);
    rep (i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a, --b;
        g.add_edge(a, b, {0, c});
        g.add_edge(b, a, {1, c});
    }

    vector dp(n, vector(m + 1, INF));
    dp[0][0] = 0;
    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;
    pq.emplace(0, 0, 0);
    while (!pq.empty()) {
        auto [d, x, y] = pq.top();
        pq.pop();
        if (dp[x][y] != d)
            continue;
        for (auto e : g[x]) {
            auto [a, b] = e.weight();
            if (y + a <= m && chmin(dp[e.to()][y + a], d + b)) {
                pq.emplace(dp[e.to()][y + a], e.to(), y + a);
            }
        }
    }

    rep (i, m + 1) {
        if (dp[n - 1][i] <= l) {
            co(i);
            return 0;
        }
    }
    co(-1);

    return 0;
}
accuracy: 0.016483516483516484
time_ms: 50
memory_kb: 10968
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;


int main() {
    int N, M, L;
    cin >> N >> M >> L;

    map<int, int> normal;
    map<int, int> reverse;
    for(int i=0; i<=N; i++) normal[i] = 10000000;
    for(int i=0; i<=N; i++) reverse[i] = 10000000;

    for(int i=0; i<M; i++) {
        vector<int> load(3);
        cin >> load[0] >> load[1] >> load[2];
        if(load[0] < load[1] && normal[load[1]] > load[2]) {
            normal[load[1]] = load[2];
        } else if(load[0] > load[1] && reverse[load[0]] > load[2]){
            reverse[load[0]] = load[2];
        }
    }

    int res = 0;
    vector<int> dp_city(N+1, 0);
    for(int i=2; i<=N; i++) {
        if(normal[i] != 10000000) {
            dp_city[i] = dp_city[i-1] + normal[i];
        } else if(reverse[i] != 10000000) {
            res++;
            dp_city[i] = dp_city[i-1] + reverse[i];
            reverse[i] = 10000000;
        } else {
            cout << -1 << endl;
            return 1;
        }
    }
    int i=0;
    while(reverse.size() > i && dp_city[N] > L) {
        i++;
        int min = 0;
        for(int j=0; j<reverse.size(); j++) {
            if(min >reverse[j]) min = j;
        }
        if(dp_city[min] > dp_city[min-1] + reverse[min]) {
            int distance = dp_city[min] - dp_city[min-1] + reverse[min];
            for(int i=min; i<=N; i++) {
                dp_city[i] -= distance;
            }
        }
        reverse[min] = 10000000;
    }
    if(dp_city[N] > L) {
        cout << -1 << endl;
    } else {
        cout << res << endl;
    }
}
accuracy: 0.06043956043956044
time_ms: 30
memory_kb: 3456
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <tuple>

using namespace std;

using Int = int_fast64_t;

const Int INF = 1LL << 62;

int main()
{
	int N, M, L; cin >> N >> M >> L;
	vector<tuple<int, int, int>> ABC(M);
	for (auto& [A, B, C] : ABC) cin >> A >> B >> C;
	vector<pair<Int, int>> D(N + 1, {INF, -1});
	using T = tuple<int, Int, int>;
	priority_queue<T, vector<T>, greater<T>> Q;
	for (Q.push({0, 0, 1}); !Q.empty();) {
		auto [r, d, n] = Q.top(); Q.pop();
		if (D[n].first <= d || d > L) continue;
		D[n] = {d, r};
		if (n == N) break;
		for (auto [A, B, C] : ABC) if (n == A) {
			Q.emplace(r, d + C, B);
		} else if (n == B) {
			Q.emplace(r + 1, d + C, A);
		}
	}
	cout << D[N].second << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3544
final_rank: 1

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>
#include <fstream>

int main() {
	int n, m, l; std::cin >> n >> m >> l;
	std::vector<std::tuple<int, int, int>> edges(m);
	for (auto& [a, b, c] : edges) {
		std::cin >> a >> b >> c; --a; --b;
	}
	std::vector<std::vector<std::pair<int, int>>> graph(n);
	std::vector<std::vector<std::pair<int, int>>> reverse(n);
	for (const auto [a, b, c] : edges) {
		graph[a].emplace_back(b, c);
		reverse[b].emplace_back(a, c);
	}
	std::vector<std::vector<int>> min_distance(n, std::vector<int>(m + 1, INT_MAX));
	min_distance[0][0] = 0;
	const auto comparator = [](const auto a, const auto b) {return a.second > b.second; };
	std::priority_queue<std::pair<std::pair<int, int>, int>, std::vector<std::pair<std::pair<int, int>, int>>, decltype(comparator)> queue(comparator);
	queue.emplace(std::make_pair(0, 0), 0);
	while (!queue.empty()) {
		const auto [pair, cost] = queue.top(); queue.pop();
		const auto [top, count] = pair;
		if (l < cost) continue;
		if (min_distance[top][count] < cost) continue;
		for (const auto [next, len]: graph[top]) {
			const auto d = cost + len;
			if (min_distance[next][count] > d) {
				min_distance[next][count] = d;
				queue.emplace(std::make_pair(next, count), d);
			}
		}
		if (count < m) {
			for (const auto [next, len] : reverse[top]) {
				const auto d = cost + len;
				if (min_distance[next][count + 1] > d) {
					min_distance[next][count + 1] = d;
					queue.emplace(std::make_pair(next, count + 1), d);
				}
			}
		}
	}
	const auto first = std::distance(min_distance.back().begin(), std::find_if(min_distance.back().begin(), min_distance.back().end(), [l](const int len) {return len <= l; }));
	if (first <= m) {
		std::cout << first << '\n';
	}
	else {
		std::cout << "-1\n";
	}
	
}
accuracy: 1
time_ms: 80
memory_kb: 11368
final_rank: 2

code_snippet: #include<iostream>
#include<algorithm>    
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<ctime>
#include<fstream>
#include<functional>
#include<map>
#include<math.h>
#include<queue>
#include<set>
#include<stack>
#include<stdio.h>
#include<string>
#include<tuple>
#include<vector>
//#include<bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i, x) for(ll i = 0; i < x; i++)
#define rep2(i, x) for(ll i = 1; i <= x; i++)
#define rep3(i, x, y) for(ll i = x; i < y; i++)
#define rep4(i, x) for(ll i = x - 1; i >= 0; i--)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define puts(x) cout << (x) << "\n"
using ll = long long;
using ld = long double;
using namespace std;
const ll INF = 1000000000000000000;
const int intINF = 1000000000;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ld pi = 3.141592653589793238;
//const ld EPS = 1e-9;
typedef string::const_iterator State;
class ParseError {};

bool isprime(int p) {
	if (p == 1) return false;
	for (int i = 2; i < p; i++) {
		if (p % i == 0) return false;
	}
	return true;
}
ll gcd(ll a, ll b) {
	if (b == 0) { return a; }
	return gcd(b, a % b);
}
//ax + by = cが整数解をもつための必要十分条件は c が gcd(a,b) で割り切れること。
// 返り値: a と b の最大公約数
// ax + by = gcd(a, b) を満たす (x, y) が格納される
//main関数内に extGCD(a, b, x, y); でx, yに解が格納
ll extGCD(ll a, ll b, ll& x, ll& y) {
	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	ll d = extGCD(b, a % b, y, x);
	y -= a / b * x;
	return d;
}
ll lcm(ll a, ll b) {
	return a / gcd(a, b) * b;
}
ll keta(ll n) {
	ll res = 0;
	while (n >= 1) {
		res++;
		//res += n % 10;

		n /= 10;
	}
	return res;
}
ll modpow(ll x, ll y, ll m) {
	ll res = 1;
	while (y) {
		if (y % 2) { res *= x; res %= m; }
		x = x * x % m; y /= 2;
	}
	return res;
}

const int nCkMAX = 500000;
ll fac[nCkMAX], finv[nCkMAX], inv[nCkMAX];//n!、1/n!、1/n
// テーブルを作る前処理
void nCkinit(ll m) {
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for (int i = 2; i < nCkMAX; i++) {
		fac[i] = fac[i - 1] * i % m;
		inv[i] = m - inv[m % i] * (m / i) % m;
		finv[i] = finv[i - 1] * inv[i] % m;
	}
}
// 二項係数計算
ll nCk(ll n, ll k, ll m) {
	if (n < k) return 0;
	if (n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n - k] % m) % m;
}
//nが大きくてkが小さい時
//nCkMAXはk+2まででOK
ll nCk2(ll n, ll k, ll m) {
	ll res = 1;
	for (int i = n - k + 1; i <= n; i++) {
		res *= i; res %= m;
	}
	res = res * finv[k] % m;
	return res;
}

//xorshift　from 「ビット演算 (bit 演算) の使い方を総特集！ 」
//1~6まで出したいときは
//xorshift() % 6 + 1
unsigned int xorshift() {
	static unsigned int tx = 123456789, ty = 362436069, tz = 521288629, tw = 88675123;
	unsigned int tt = (tx ^ (tx << 11));
	tx = ty; ty = tz; tz = tw;
	return (tw = (tw ^ (tw >> 19)) ^ (tt ^ (tt >> 8)));
}


//printf("%.10f\n", n);
typedef pair <ll, ll> P;
typedef pair <ld, ll> pp;
ll dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };


vector<ll> spf;
void smallest_prime_factors(ll n) {
	spf.resize(n + 1); spf[1] = 1;
	for (int i = 2; i <= n; i++) {
		if (!spf[i]) {
			for (int j = i; j < n; j += i) { spf[j] = i; }
		}
	}
}
std::map<int, int> high_speed_prime_factor(int n) {
	std::map<int, int> res;
	while (n != 1) {
		res[spf[n]]++;
		n /= spf[n];
	}
	return res;
}

////////////////////////////////struct
/*struct edge {
	ll to; ld cost;
};*/
struct Point {
	ll x, y;
};
bool operator<(const Point& a1, const Point& a2) {
	if (a1.x < a2.x) return true;
	if (a1.x > a2.x) return false;
	if (a1.y < a2.y) return true;
	return false;
}
struct status {
	ll first;
	ll second;
	ll kai;

	//bool operator<(const status& rhs) const { return c < rhs.c; };
	//bool operator>(const status& rhs) const { return c > rhs.c; };
	bool operator<(const status& rhs) const { return first < rhs.first; };
	bool operator>(const status& rhs) const { return first > rhs.first; };
};
void yesno(bool ok) {
	if (ok) { cout << "Yes\n"; }
	else { cout << "No\n"; }
}
//多倍長整数演算
//nCkを求めるときにnCkMAXとnCkinit

//O(ElogV)
//const ll INF = 10000000000000;
struct edge { ll to, cost; };
//typedef pair<ll, ll>P; //firstは最短距離、secondは頂点番号

//負の辺は本当にないですか？？？

ll d[1456][1234];//始点sから終点tまでのコストd[t]
vector<edge> G[213456];//コスト
vector<edge> rG[213456];//コスト
void dijkstra(ll s) {
	//greater<P>を指定→firstが小さい順
	priority_queue<status, vector<status>, greater<status> >que;
	d[s][0] = 0; que.push({0, s, 0});
	while (!que.empty()) {
		status p = que.top(); que.pop();
		int v = p.second;
		if (d[v][p.kai] < p.first) { continue; }
		for (int i = 0; i < G[v].size(); i++) {
			edge e = G[v][i];
			if (d[e.to][p.kai] > d[v][p.kai] + e.cost) {
				d[e.to][p.kai] = d[v][p.kai] + e.cost;
				que.push({ d[e.to][p.kai], e.to, p.kai });
			}
		}
		if (p.kai > 1000) { continue; }
		rep(i, rG[v].size()) {
			edge e = rG[v][i];
			if (d[e.to][p.kai + 1] > d[v][p.kai] + e.cost) {
				d[e.to][p.kai + 1] = d[v][p.kai] + e.cost;
				que.push({ d[e.to][p.kai + 1], e.to, p.kai + 1 });
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	//cout << fixed << setprecision(15);

	rep(i, 1234) {
		rep(j, 1234) {
			d[i][j] = INF;
		}
	}
	ll n, m, l; cin >> n >> m >> l;
	rep(i, m) {
		ll a, b, c; cin >> a >> b >> c;
		G[a].push_back({ b, c });
		rG[b].push_back({ a,c });
	}
	dijkstra(1);
	ll ans = INF;
	rep(i, 1001) {
		if (d[n][i] <= l) { ans = min(ans, i); }
	}
	cout << (ans == INF ? - 1 : ans) << endl;
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 35632
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define drep(i,j,n) for(int i=0;i<(int)(n-1);i++)for(int j=i+1;j<(int)(n);j++)
#define trep(i,j,k,n) for(int i=0;i<(int)(n-2);i++)for(int j=i+1;j<(int)(n-1);j++)for(int k=j+1;k<(int)(n);k++)
#define codefor int test;scanf("%d",&test);while(test--)
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define yes(ans) if(ans)printf("yes\n");else printf("no\n")
#define Yes(ans) if(ans)printf("Yes\n");else printf("No\n")
#define YES(ans) if(ans)printf("YES\n");else printf("NO\n")
#define popcount(v) __builtin_popcountll(v)
#define vector2d(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define vector3d(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
#define vector4d(type,name,h,w,d,...) vector<vector<vector<vector<type>>>>name(h,vector<vector<vector<type>>>(w,vector<vector<type>>(d,vector<type>(__VA_ARGS__))))
using namespace std;
using ll = long long;
template<class T> using rpriority_queue = priority_queue<T, vector<T>, greater<T>>;
const int MOD=1000000007;
const int MOD2=998244353;
const int INF=1<<30;
const ll INF2=1LL<<60;
void scan(int& a){scanf("%d",&a);}
void scan(long long& a){scanf("%lld",&a);}
template<class T,class L>void scan(pair<T, L>& p){scan(p.first);scan(p.second);}
template<class T,class U,class V>void scan(tuple<T,U,V>& p){scan(get<0>(p));scan(get<1>(p));scan(get<2>(p));}
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i);}
template<class T> void scan(T& a){cin>>a;}
template<class T> void scan(vector<T>& vec){for(auto&& it:vec)scan(it);}
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){scan(head);in(tail...);}
void print(const int& a){printf("%d",a);}
void print(const long long& a){printf("%lld",a);}
void print(const double& a){printf("%.15lf",a);}
template<class T,class L>void print(const pair<T, L>& p){print(p.first);putchar(' ');print(p.second);}
template<class T> void print(const T& a){cout<<a;}
template<class T> void print(const vector<T>& vec){if(vec.empty())return;print(vec[0]);for(auto it=vec.begin();++it!= vec.end();){putchar(' ');print(*it);}}
void out(){putchar('\n');}
template<class T> void out(const T& t){print(t);putchar('\n');}
template <class Head, class... Tail> void out(const Head& head,const Tail&... tail){print(head);putchar(' ');out(tail...);}
template<class T> void dprint(const T& a){cerr<<a;}
template<class T> void dprint(const vector<T>& vec){if(vec.empty())return;cerr<<vec[0];for(auto it=vec.begin();++it!= vec.end();){cerr<<" "<<*it;}}
void debug(){cerr<<endl;}
template<class T> void debug(const T& t){dprint(t);cerr<<endl;}
template <class Head, class... Tail> void debug(const Head& head, const Tail&... tail){dprint(head);cerr<<" ";debug(tail...);}
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll modinv(ll a, ll m) {ll b = m, u = 1, v = 0;while (b) {ll t = a / b;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;}
ll updivide(ll a,ll b){return (a+b-1)/b;}
int msb(ll v){return 63-__builtin_clzll(v);}
template<class T> void chmax(T &a,const T b){if(b>a)a=b;}
template<class T> void chmin(T &a,const T b){if(b<a)a=b;}

int main(){
    INT(n,m,l);
    vector<vector<array<int,3>>> g(n);
    int u,v,c;
    rep(i,m){
        in(u,v,c);
        u--,v--;
        g[u].push_back({v,c,0});
        g[v].push_back({u,c,1});
    }
    vector2d(int,dist,n,m+1,INF);
    //距離、頂点、反転回数
    rpriority_queue<array<int,3>> pq;
    dist[0][0]=0;
    pq.push({0,0,0});
    while(!pq.empty()){
        auto a=pq.top();
        pq.pop();
        for(auto b:g[a[1]]){
            if(a[2]+b[2]>m)continue;
            if(a[0]+b[1]>=dist[b[0]][a[2]+b[2]])continue;
            dist[b[0]][a[2]+b[2]]=a[0]+b[1];
            pq.push({a[0]+b[1],b[0],a[2]+b[2]});
        }
    }
    for(int i=0;i<=m;i++){
        if(dist[n-1][i]<=l){
            out(i);
            return 0;
        }
    }
    out(-1);
}
accuracy: 1
time_ms: 130
memory_kb: 11632
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001





#define SIZE 1005

struct Edge{
	Edge(int arg_to,ll arg_dist,bool arg_is_rev){
		to = arg_to;
		dist = arg_dist;
		is_rev = arg_is_rev;
	}
	int to;
	ll dist;
	bool is_rev;
};


struct State{
	State(){

		node = num_rev = 0;
		sum_dist = 0;
	}
	State(int arg_node,ll arg_sum_dist,int arg_num_rev){
		node = arg_node;
		sum_dist = arg_sum_dist;
		num_rev = arg_num_rev;
	}
	bool operator<(const struct State& arg) const{

		return sum_dist > arg.sum_dist; //昇順(PQ)
	}

	int node,num_rev;
	ll sum_dist;
};

int N,E;
ll base_dist;
ll min_dist[SIZE][SIZE];
vector<Edge> G[SIZE];

void calc_dist(int start){

	for(int i = 0; i < N; i++){
		for(int k = 0; k <= N; k++){
			min_dist[i][k] = HUGE_NUM;
		}
	}

	min_dist[start][0] = 0; //min_dist[node][反転回数] = 最小コスト
	priority_queue<State> Q;

	Q.push(State(start,0,0));

	while(!Q.empty()){

		State state = Q.top(); //都度取り出し(マイナスのsum_dist対策)
		Q.pop();

		if(state.sum_dist > min_dist[state.node][state.num_rev]){

			continue;
		}

		for(int i = 0; i < G[state.node].size(); i++){

			int next_node = G[state.node][i].to;
			ll next_dist = state.sum_dist + G[state.node][i].dist;
			int next_rev = state.num_rev;
			if(G[state.node][i].is_rev){

				next_rev++;
			}
			if(next_rev == N+1)continue;

			if(min_dist[next_node][next_rev] > next_dist){

				min_dist[next_node][next_rev] = next_dist;
				Q.push(State(next_node,next_dist,next_rev));
			}
		}
	}
}


int main(){

	scanf("%d %d %lld",&N,&E,&base_dist);

	int from,to;
	ll dist;

	for(int loop = 0; loop < E; loop++){

		scanf("%d %d %lld",&from,&to,&dist);
		from--;
		to--;

		G[from].push_back(Edge(to,dist,false));
		G[to].push_back(Edge(from,dist,true));
	}

	calc_dist(0);

	for(int k = 0; k <= N; k++){
		if(min_dist[N-1][k] <= base_dist){

			printf("%d\n",k);
			return 0;
		}
	}

	printf("-1\n");

	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 14924
final_rank: 4