Problem:
Problem D: One-Time Path
Problem
N
個の島と
M
本の橋がある。
N
個の島にはそれぞれ1から
N
までの番号が割り振られている。
M
本の橋にもそれぞれ1から
M
までの番号が割り振られている。
がっちょ君は現在(時刻0の時点で)、1番目の島にいる。
がっちょ君は
i
番目の橋を利用することにより、
a
i
番目の島から
b
i
番目の島へと単方向に移動することができる。
しかし、時刻0の時点では、すべての橋は潮が満ちていて海の中に沈んでしまっている。
i
番目の橋は、時刻
c
i
になると潮が引いて渡れるようになる。
そして、時刻
c
i
を過ぎると、すぐにまた潮が満ちて
i
番目の橋は再び沈んでしまう。
再び沈んでしまうと、またいつ潮が引いて渡れるようになるかはわからない。
そこで、がっちょ君はそうなった橋は永遠に渡れなくなると考えるようにした。
がっちょ君は、できるだけ長い間、1から
N
-1番目の島の景色を眺めていたいのだが、
N
番目の島に船を泊めてあるので、最終的には
N
番目の島に到着していなければならない。また、船の中で両親を待たせているため、がっちょ君は
N
番目の島についたらすぐに船で出発して家へと帰らなければならない。
がっちょ君が橋を渡ったり島の中を移動する時間はとても短いので、0と仮定してよい。がっちょ君が1から
N
-1番目のいずれかの島にいることのできる時間の最大値を求めよ。ただし、どのように移動してもがっちょ君が
N
番目の島へと移動できない場合は代わりに-1を出力せよ。
Input
入力は以下の形式で与えられる。
N
M
a
1
b
1
c
1
a
2
b
2
c
2
…
a
M
b
M
c
M
1行目には、2つの整数
N
,
M
が空白区切りで与えられる。
2行目から
M
+1行目のそれぞれの行
i
には、3つの整数
a
i
,
b
i
,
c
i
が空白区切りで与えられる。
Constraints
2 ≤
N
≤ 10
5
1 ≤
M
≤ 2 × 10
5
1 ≤
a
i
<
N
1 ≤
b
i
≤
N
1 ≤
c
i
≤ 10
9
a
i
≠
b
i
Output
がっちょ君が
N
番目の島へと移動できる場合は、がっちょ君が1から
N
-1番目のいずれかの島にいることのできる時間の最大値を出力する。
N
番目の島へと移動できない場合は、代わりに-1を出力する。
Sample Input 1
3 2
1 2 10
2 3 20
Sample Output 1
20
まず、1番目の島で時刻が10になるまで待ってから、2番目の島へと移動する。
次に、2番目の島で時刻が20になるまで待ってから、3番目の島へと移動する。
以上より、1から2番目のいずれかの島にいる時間は20となる。
Sample Input 2
4 4
1 2 27
1 3 37
2 3 47
3 1 57
Sample Output 2
-1
4番目の島に繋がる橋がないため、4番目の島へ移動することができない。
Sample Input 3
3 3
1 2 13
2 3 17
2 3 15
Sample Output 3
17
Sample Input 4
3 2
1 2 20
2 3 10
Sample Output 4
-1
Sample Input 5
3 2
1 2 10
2 3 10
Sample Output 5
10

Submitted solutions:

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
template<class S,class T> ostream& operator << (ostream& out,const pair<S,T>& o){ out << "(" << o.first << "," << o.second << ")"; return out; }
template<class T> ostream& operator << (ostream& out,const vector<T> V){ for(int i = 0; i < V.size(); i++){ out << V[i]; if(i!=V.size()-1) out << " ";} return out; }
template<class T> ostream& operator << (ostream& out,const vector<vector<T> > Mat){ for(int i = 0; i < Mat.size(); i++) { if(i != 0) out << endl; out << Mat[i];} return out; }
template<class S,class T> ostream& operator << (ostream& out,const map<S,T> mp){ out << "{ "; for(auto it = mp.begin(); it != mp.end(); it++){ out << it->first << ":" << it->second; if(mp.size()-1 != distance(mp.begin(),it)) out << ", "; } out << " }"; return out; }

/*
 <url:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1590>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */


ll solve(){
    ll res = -1;
    ll N,M; cin >> N >> M;
    vector<vector<pll>> G(N);
    using Event = tuple<ll,ll,ll>;
    vector<Event> E;
    for(int i = 0; i < M;i++){
        ll a,b,c; cin >> a >> b >> c;
        a--; b--;
        E.push_back(Event(a,b,c));
    }
    sort(E.begin(),E.end(),[](const Event & e1,const Event& e2){
        return std::get<2>(e1) < std::get<2>(e2);
    });
    
    
    vector<int> flag(N); flag[0] = 1;
    vector<Event> event;
    int idx = 0;
    ll nowT = 0;
    while(idx < M){
        ll a,b,c; tie(a,b,c) = E[idx++];
        if(nowT == c) {
            event.push_back(Event(a,b,c));
        }else{
            nowT = c;
            bool update = false;
            while(true){
                update = false;
                for(int i = 0; i < event.size();i++){
                    ll u,v,T; tie(u,v,T) = event[i];
                    if(flag[u]){
                        if(flag[v]){
                            if(v == N-1) res = max(res,T);
                            continue;
                            //event.erase(event.begin()+i);
                        }else{
                            flag[v] = 1;
                            update = true;
                        }
                    }
                }
                if(update) continue;
                break;
            }
            event.clear();
            event.push_back(Event(a,b,c));
        }
    }
    bool update = false;
    while(true){
        update = false;
        for(int i = 0; i < event.size();i++){
            ll u,v,T; tie(u,v,T) = event[i];
            if(flag[u]){
                if(flag[v]){
                    if(v == N-1) res = max(res,T);
                    continue;
                    //event.erase(event.begin()+i);
                }else{
                    flag[v] = 1;
                    update = true;
                }
            }
        }
        if(update) continue;
        break;
    }
    return res;
}
int main(void) {
    cin.tie(0); ios_base::sync_with_stdio(false);
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 14860
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
using P = pair<int, int>;

int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<P>> G(n);
    for(int i = 0; i < m; i++){
        int a, b, c; cin >> a >> b >> c;
        a--; b--;
        G[a].emplace_back(c, b);
        // G[b].emplace_back(c, a);
    }

    vector<int> t(n, 1 << 30);
    t[0] = 0;
    priority_queue<P, vector<P>, greater<P>> Q;
    Q.emplace(0, 0);
    while(!Q.empty()){
        auto c = Q.top(); Q.pop();
        if(t[c.second] < c.first) continue;
        for(auto &nex: G[c.second]){
            if(t[nex.second] > nex.first && nex.first >= c.first){
                t[nex.second] = nex.first;
                Q.emplace(nex.first, nex.second);
            }
        }
    }
    int ans = -(1 << 30);
    for(int i = 0; i < n-1; i++){
        for(auto &nex: G[i]){
            if(nex.second != n-1) continue;
            if(t[i] <= nex.first) ans = max(ans, nex.first);
        }
    }
    if(ans == -(1 << 30)) ans = -1;
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 9012
final_rank: 11

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>

using namespace std;

int N,M;
const int MAXN=1e5+7;
using edge_t=pair<int,int>;
vector<edge_t> graph[MAXN];
int dist[MAXN];

const int INF=1e9+7;
int main(){
    scanf("%d%d",&N,&M);
    for(int i=0;i<M;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        graph[a].push_back({-c,b});
    }

    fill(dist+1,dist+N+1,INF);

    priority_queue<pair<int,int>> q;
    q.push({0,1});
    while(!q.empty()){
        int d=-q.top().first,v=q.top().second;
        q.pop();
        if (dist[v]<=d) continue;
        dist[v]=d;
        for(auto e:graph[v])
            if (e.first+d<=0) q.push({e.first,e.second});
    }

    int ans=-1;
    for(int v=1;v<N;v++){
        for(auto e:graph[v]){
            if (e.first+dist[v]>0) continue;
            if (e.second!=N) continue;
            ans=max(ans,-e.first);
        }
    }

    printf("%d\n",ans);


    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 9696
final_rank: 5

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

using i64 = int64_t;

constexpr int INF = 1e9 + 100;

struct Edge{
    int from, to, c;
};

struct State{
    int num, tm;
    bool operator<(const State &rhs)const{
        return tm > rhs.tm;
    }
};

using Graph = vector<vector<Edge>>;

int main(){
    int n, m;
    cin >> n >> m;
    Graph graph(n+1, vector<Edge>());
    for(int i=0;i<m;++i){
        int a, b, c;
        cin >> a >> b >> c;
        graph[a].push_back((Edge){a, b, c});
    }

    vector<int> mini(n+1, INF);
    mini[1] = 0;
    priority_queue<State> que;
    que.push((State){1, 0});
    int ans = -1;
    while(!que.empty()){
        auto cur = que.top(); que.pop();
        if(mini[cur.num] < cur.tm)continue;
        for(auto e: graph[cur.num]){
            if(cur.tm > e.c)continue;
            if(e.to == n){
                ans = max(ans, e.c);
            }else{
                if(e.c >= mini[e.to])continue;
                mini[e.to] = e.c;
                que.push((State){e.to, e.c});
            }
        }
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 9004
final_rank: 15

code_snippet: #include<algorithm>
#include<bitset>
#include<cassert>
#include<cfloat>
#include<climits>
#include<cmath>
#include<deque>
#include<functional>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

using lint = long long;
using P = pair<int, int>;
using LLP = pair<long long, long long>;

#define REP(i, x, n) for(int i = (x), i##_len = (int)(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = (int)(n) ; i < i##_len ; ++i)
#define reps(i, n) for(int i = 1, i##_len = (int)(n) ; i <= i##_len ; ++i)
#define rrep(i, n) for(int i = (int)(n) - 1 ; i >= 0 ; --i)
#define rreps(i, n) for(int i = (int)(n) ; i > 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())
#define REVERSE(x) reverse((x).begin(), (x).end())
#define TWINS(x) cout << ((x) ? "Yay!" : ":(") << '\n'
#define endl '\n'

constexpr int IINF = (1 << 30) - 1;
constexpr long long LLINF = 1LL << 61;
constexpr double EPS = 1e-10;

constexpr int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
constexpr int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};

struct edge{
    int to, cost;
};

struct node{
    int id, cost;

    bool operator<(const node& rhs) const {
        return cost > rhs.cost;
    }
};

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

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

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    int n, m;
    cin >> n >> m;

    vector< vector<edge> > g(n);
    rep(i, m){
        int a, b, c;
        cin >> a >> b >> c;
        g[--a].push_back({--b, c});
    }

    vector<int> cost(n, IINF);
    cost[0] = 0;
    priority_queue<node> que;
    que.push({0, 0});

    int ans = -1;

    while(!que.empty()){
        node now = que.top();
        que.pop();
        if(cost[now.id] < now.cost){
            continue;
        }
        for(auto e : g[now.id]){
            if(now.cost > e.cost){
                continue;
            }
            if(e.to == n - 1){
                chmax(ans, e.cost);
            }else if(chmin(cost[e.to], e.cost)){
                que.push({e.to, e.cost});
            }
        }
    }

    cout << ans << endl;

    cout << flush;

    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 8624
final_rank: 2

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 1590.cc: One-Time Path
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 100000;
const int INF = 1 << 30;

/* typedef */

typedef pair<int,int> pii;
typedef vector<pii> vpii;

/* global variables */

vpii nbrs[MAX_N];
int ds[MAX_N];

/* subroutines */

/* main */

int main() {
  int n, m;
  scanf("%d%d", &n, &m);

  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    //nbrs[a].push_back(pii(b, c));
    nbrs[b].push_back(pii(a, c));
  }

  int st = 0, gl = n - 1;
  int maxd = -1;
  vpii &nbrgl = nbrs[gl];

  for (vpii::iterator git = nbrgl.begin(); git != nbrgl.end(); git++) {
    int &gv = git->first, &gd = git->second;
    fill(ds, ds + n, -1);
    ds[gl] = ds[gv] = gd;

    priority_queue<pii> q;
    q.push(pii(gd, gv));

    while (! q.empty()) {
      pii u = q.top(); q.pop();
      int &ud = u.first, &ui = u.second;
      if (ud != ds[ui]) continue;
      if (ui == st) break;

      vpii &nbru = nbrs[ui];

      for (vpii::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
	int &vi = vit->first, &vd = vit->second;
	if (vd <= ud && ds[vi] < vd) {
	  ds[vi] = vd;
	  q.push(pii(vd, vi));
	}
      }
    }

    if (ds[st] >= 0 && maxd < gd) maxd = gd;
  }

  printf("%d\n", maxd);
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 9536
final_rank: 4

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

using namespace std;

#define REP(i, n) for (int i = 0; i < n; ++i)

struct E {
  int from, to, c;
};

using G = vector<vector<E>>;

int main() {
  int n, m;
  cin >> n >> m;
  G g(n);
  set<pair<int, int>> st;
  REP(i, m) {
    int a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    if (b == n - 1)
      st.insert({a, c});
    else
      g[a].push_back({a, b, c});
  }
  using P = pair<int, int>;
  constexpr int INF = 1e9 + 1;
  vector<int> d(n, INF);
  d[0] = 0;
  priority_queue<P, vector<P>, greater<>> q;
  q.push({0, 0});
  while (!q.empty()) {
    P p = q.top();
    q.pop();
    if (p.first > d[p.second])
      continue;
    for (auto e : g[p.second]) {
      if (e.c >= d[p.second] && d[e.to] > e.c) {
        d[e.to] = e.c;
        q.push({e.c, e.to});
      }
    }
  }

  int ans = -1;
  for (auto a : st) {
    if (d[a.first] <= a.second)
      ans = max(ans, a.second);
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 8996
final_rank: 14

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<utility>
#include<map>
#include<complex>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
#define rep(i,n) for(int i=0;i<n;i++)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define stop char nyaa;cin>>nyaa;
#define per(i,n) for(int i=n-1;i>=0;i--)

//geometry
typedef long double ld;
typedef complex<ld> Point;
const ld pi = acos(-1.0);
ld dot(Point a, Point b) { return real(conj(a)*b); }
ld cross(Point a, Point b) { return imag(conj(a)*b); }

struct Line {
	Point a, b;
};

Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a;
	Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}

vector<int> ans;
//scc
struct graph {
private:
	int n; vector<vector<int>> G, rG;
	vector<bool> used;
	vector<int> vs;

	int mk;
	vector<vector<int>> fG;
	vector<vector<int>> ori;
	vector<int> trans;
public:
	graph(int sz) {
		n = sz;
		G.resize(n);
		rG.resize(n);
		used.resize(n);

		fG.resize(n);
		trans.resize(n, -1);
		ori.resize(n);
	}
	void add_edge(int a, int b) {
		G[a].push_back(b);
		rG[b].push_back(a);
	}
	void dfs(int v) {
		used[v] = true;
		rep(i, G[v].size()) {
			if (!used[G[v][i]])dfs(G[v][i]);
		}
		vs.push_back(v);
	}
	void rdfs(int v, int k) {
		used[v] = true;
		queue<int> q;
		q.push(v);
		vector<int> c;
		while (!q.empty()) {
			int id = q.front(); q.pop();
			ori[k].push_back(id);
			rep(j, rG[id].size()) {
				int to = rG[id][j];
				if (used[to]) {
					if (trans[to] >= 0)c.push_back(trans[to]);
					continue;
				}
				used[to] = true; q.push(to);
			}
		}
		sort(c.begin(), c.end());
		int len = unique(c.begin(), c.end()) - c.begin();
		rep(i, len) {
			fG[c[i]].push_back(k);
		}
		rep(i, ori[k].size()) {
			trans[ori[k][i]] = k;
		}
	}
	void scc() {
		fill(used.begin(), used.end(), false);
		rep(i, n)if (!used[i])dfs(i);
		fill(used.begin(), used.end(), false);
		int k = 0;
		per(i, (int)vs.size()) {
			if (!used[vs[i]]) {
				rdfs(vs[i], k); k++;
			}
		}
		mk = k;
	}
	void query(vector<int> &x,int &cur,int &sz) {
		vector<int> c(mk, 0);
		vector<int> val(mk, -1);
		rep(i, mk) {
			rep(j, ori[i].size()) {
				val[i] = max(val[i], ans[x[ori[i][j]]]);
				if (x[ori[i][j]] == sz - 1) {
					val[i] = max(val[i], cur);
				}
			}
		}
		rep(i, mk) {
			rep(j, fG[i].size()) {
				int to = fG[i][j];
				c[to]++;
			}
		}
		queue<int> q;
		rep(i, mk)if (c[i] == 0)q.push(i);
		while (!q.empty()) {
			int id = q.front(); q.pop();
			rep(j, fG[id].size()) {
				int to = fG[id][j]; c[to]--;
				if (c[to] == 0) {
					q.push(to);
				}
				val[to] = max(val[to], val[id]);
			}
		}
		rep(i, mk) {
			rep(j, ori[i].size()) {
				if (x[ori[i][j]] == sz - 1)continue;
				ans[x[ori[i][j]]] = val[i];
			}
		}
	}
};


void to_unique(vector<int> &v) {
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
}
void solve() {
	int n, m; cin >> n >> m;
	ans.resize(n, -1);
	vector<pair<int, P>> v;
	rep(i, m) {
		int a, b, c; cin >> a >> b >> c;
		a--; b--;
		if (a == n - 1)continue;
		v.push_back({ c,{ b,a } });
	}
	sort(v.begin(), v.end(), greater<pair<int,P>>());
	rep(i, v.size()) {
		int le = i;
		while (i + 1 < (int)v.size() && v[i].first == v[i + 1].first) {
			i++;
		}
		if (i == le) {
			int id = v[i].second.first; int to = v[i].second.second;
			ans[to] = max(ans[to], ans[id]);
			if (id == n - 1)ans[to] = max(ans[to], v[i].first);
			continue;
		}
		vector<int> x;
		vector<P> u;
		Rep(j, le, i+1) {
			u.push_back(v[j].second);
			x.push_back(v[j].second.first);
			x.push_back(v[j].second.second);
		}
		to_unique(x);
		{
			map<int, int> mp;
			rep(j, x.size()) {
				mp[x[j]] = j;
			}
			rep(j, u.size()) {
				u[j].first = mp[u[j].first];
				u[j].second = mp[u[j].second];
			}
		}
		graph g(x.size());
		rep(j, u.size()) {
			//cout << x[u[j].first] << " " << x[u[j].second] << endl;
			g.add_edge(u[j].first, u[j].second);
		}
		g.scc(); g.query(x,v[i].first,n);
	}
	//rep(i, n)cout << ans[i] << endl;
	cout << ans[0] << endl;
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	solve();
	//stop
		return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 20572
final_rank: 18

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

const int INF = 1<<30;

int main(){
    int n, m;
    cin >> n >> m;
    vector<pair<int,int>> v[n];
    int a, b, c;
    while(m-- > 0){
        cin >> a >> b >> c;
        a--, b--;
        v[a].push_back({b,c});
    }
    priority_queue<pair<int,int>> pq;
    pq.push({-0, 0});
    vector<int> d(n, 1<<30);
    int ans = 0;
    while(!pq.empty()){
        pair<int,int> p = pq.top(); pq.pop();
        int cost = -p.first, pos = p.second;
        if(d[pos] <= cost)  continue;
        d[pos] = cost;
        for(pair<int,int> q : v[pos]){
            int to = q.first, c = q.second;
            if(cost > c)    continue;
            if(to == n-1){
                ans = max(ans, c);
            }else if(d[to] > c){
                pq.push({-c, to});
            }
        }
    }
    cout << (ans == 0 ? -1 : ans) << endl;
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 8636
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int,P> P3;
typedef pair<double, P3> P4;
const ll MOD = ll(1e9+7);
const int IINF = INT_MAX;
const ll LLINF = LLONG_MAX;
const int MAX_N = int(1e5 + 5);
const double EPS = 1e-6;
const int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define ALL(v) (v).begin(), (v).end()

int n, m, dmin[MAX_N],dmax[MAX_N];
vector<vector<P> > g;

int dijkstra(){
    fill(dmax, dmax+n, -1);
    fill(dmin, dmin+n, IINF);
    priority_queue<P, vector<P>, greater<P> > que;
    que.push({0,0});
    while(!que.empty()){
        P p = que.top();
        que.pop();
        int t = p.first, v = p.second;
        if(dmin[v] < t)continue;
        for(auto &e : g[v]){
            int u = e.first, c = e.second;
            if(c < t)continue;
            if(dmin[u] > c){
                dmin[u] = c;
                que.push({c,u});
            }
            dmax[u] = max(dmax[u],c);
        }
    }
}

int main() {
    cin >> n >> m;
    g.resize(n);
    REP(i,m){
        int a, b, c;
        cin >> a >> b >> c;
        a--; b--;
        g[a].push_back({b,c});
    }
    dijkstra();
    if(dmin[n-1]==IINF){
        cout << -1 << endl;
    }
    else{
        cout << dmax[n-1] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 8920
final_rank: 13

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

const int INF = (1 << 30) - 1;

struct Edge
{
    int to, time;
    Edge () {}
    Edge ( int to, int time ) : to(to), time(time) {}
};

int N, M;
using T = pair < int , int >;
priority_queue < T , vector < T > , greater < T > > pq;
int min_cost[100005];
vector < Edge > G[100005];

int main()
{
    int maxv = -1;

    scanf("%d %d", &N, &M);

    while ( M-- ) {
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c); --a, --b;
        G[a].emplace_back(b, c);
    }

    fill_n(min_cost, 100005, INF);
    min_cost[0] = 0;
    pq.emplace(0, 0);

    while ( !pq.empty() ) {
        T d = pq.top(); pq.pop();
        if ( d.first > min_cost[d.second] ) continue;
        for ( auto x : G[d.second] ) {
            if ( x.to == N - 1 ) {
                if ( d.first <= x.time ) {
                    maxv = max(maxv, x.time);
                }
            } else {
                if ( d.first <= x.time && x.time < min_cost[x.to] ) {
                    min_cost[x.to] = x.time;
                    pq.emplace(x.time, x.to);
                }
            }
        }
    }
    cout << maxv << endl;

    return ( 0 );
}
accuracy: 1
time_ms: 40
memory_kb: 9532
final_rank: 3

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
template<class S,class T> ostream& operator << (ostream& out,const pair<S,T>& o){ out << "(" << o.first << "," << o.second << ")"; return out; }
template<class T> ostream& operator << (ostream& out,const vector<T> V){ for(int i = 0; i < V.size(); i++){ out << V[i]; if(i!=V.size()-1) out << " ";} return out; }
template<class T> ostream& operator << (ostream& out,const vector<vector<T> > Mat){ for(int i = 0; i < Mat.size(); i++) { if(i != 0) out << endl; out << Mat[i];} return out; }
template<class S,class T> ostream& operator << (ostream& out,const map<S,T> mp){ out << "{ "; for(auto it = mp.begin(); it != mp.end(); it++){ out << it->first << ":" << it->second; if(mp.size()-1 != distance(mp.begin(),it)) out << ", "; } out << " }"; return out; }

/*
 <url:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1590>
 問題文============================================================
 =================================================================
 解説=============================================================
 ================================================================
 */


ll solve(){
    ll res = -1;
    ll N,M; cin >> N >> M;
    vector<vector<pll>> G(N);
    using Event = tuple<ll,ll,ll>;
    vector<Event> E;
    for(int i = 0; i < M;i++){
        ll a,b,c; cin >> a >> b >> c;
        a--; b--;
        E.push_back(Event(a,b,c));
    }
    sort(E.begin(),E.end(),[](const Event & e1,const Event& e2){
        return std::get<2>(e1) < std::get<2>(e2);
    });
    
    
    vector<int> flag(N); flag[0] = 1;
    vector<Event> event;
    int idx = 0;
    ll nowT = 0;
    while(idx < M){
        ll a,b,c; tie(a,b,c) = E[idx++];
        if(nowT == c) {
            event.push_back(Event(a,b,c));
        }else{
            nowT = c;
            bool update = false;
            while(true){
                update = false;
                for(int i = 0; i < event.size();i++){
                    ll u,v,T; tie(u,v,T) = event[i];
                    if(flag[u]){
                        if(flag[v]){
                            if(v == N-1) res = max(res,T);
                            continue;
                            //event.erase(event.begin()+i);
                        }else{
                            flag[v] = 1;
                            update = true;
                        }
                    }
                }
                if(update) continue;
                break;
            }
            event.clear();
            event.push_back(Event(a,b,c));
        }
    }
    bool update = false;
    while(true){
        update = false;
        for(int i = 0; i < event.size();i++){
            ll u,v,T; tie(u,v,T) = event[i];
            if(flag[u]){
                if(flag[v]){
                    if(v == N-1) res = max(res,T);
                    continue;
                    //event.erase(event.begin()+i);
                }else{
                    flag[v] = 1;
                    update = true;
                }
            }
        }
        if(update) continue;
        break;
    }
    return res;
}
int main(void) {
    cin.tie(0); ios_base::sync_with_stdio(false);
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 13676
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct E{
  ll to,cost;
  E(ll to,ll cost):to(to),cost(cost){}
};
typedef pair<ll,ll> P;
int main(){
  ll n,m,i,j,k,a,b,c;
  cin>>n>>m;
  vector<E> v[n];
  vector<E> can;
  for(i=0;i<m;i++){
    cin >> a >> b >> c;
    a--;b--;
    if(b==n-1) can.push_back(E(a,c));
    else v[a].push_back(E(b,c));
  }
  ll g[n];
  memset(g,-1,sizeof(g));
  priority_queue<P,vector<P>,greater<P> > q;
  q.push(P(1,0));
  while(!q.empty()){
    P p=q.top();q.pop();
    b=p.first;a=p.second;
    if(~g[a]&&g[a]<=b) continue;
    g[a]=b;
    for(i=0;i<v[a].size();i++){
      if(b<=v[a][i].cost)
	if(!~g[v[a][i].to]||g[v[a][i].to]>v[a][i].cost)
	  q.push(P(v[a][i].cost,v[a][i].to));
    }
  }
  ll ans=-1;
  for(i=0;i<can.size();i++)
    if(~g[can[i].to]&&g[can[i].to]<=can[i].cost) ans=max(ans,can[i].cost);
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 12020
final_rank: 17

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;


int main() {
	int N,M;cin>>N>>M;
	vector<vector<pair<int,int>>>edges(N);
	vector<int>memo(N-1,1e9+1e7);
	memo[0]=0;

	for (int i = 0; i < M; ++i) {
		int a,b,c;cin>>a>>b>>c;
		a--;b--;
		edges[a].push_back(make_pair(b,c));
	}

	priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>que;
	que.push(make_pair(0,0));
	while (!que.empty()) {
		auto atop(que.top());
		que.pop();
		const int now=atop.second;
		const int now_time=atop.first;
		if(memo[now]<now_time)continue;
		for (auto e : edges[now]) {
			if(e.first==N-1)continue;
			if (e.second >= now_time) {
				if (memo[e.first] > e.second) {
					que.push(make_pair(e.second,e.first));
					memo[e.first]=e.second;
				}
			}
		}
	}

	int ans=-1;
	for (int i = 0; i < N - 1; ++i) {
		for (auto e : edges[i]) {
			if (e.first==N-1&&memo[i] <= e.second) {
				ans=max(ans,e.second);
			}
		}
	}
	{
		cout<<ans<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 8704
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pi = pair<int,int>;
using E = pair<int,pi>;

int main()
{
    int n,m;
    cin >>n >>m;

    vector<E> e(m);
    rep(i,m)
    {
        int a,b,c;
        cin >>a >>b >>c;
        --a;
        --b;
        e[i] = {c,{a,b}};
    }
    sort(all(e));

    int ans = -1;
    vector<bool> vis(n);
    vis[0] = true;
    rep(i,m)
    {
        pi p = e[i].se;

        if(vis[p.fi])
        {
            vis[p.se] = true;
            if(p.se == n-1) ans = e[i].fi;
        }
    }

    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 5108
final_rank: 1

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	Info(int arg_to,int arg_time){
		to = arg_to;
		time = arg_time;
	}
	int to,time;
};

struct Data{
	Data(int arg_node_id,int arg_current_time){
		node_id = arg_node_id;
		current_time = arg_current_time;
	}
	bool operator<(const struct Data &arg) const{
		return current_time > arg.current_time;
	}
	int node_id,current_time;
};

vector<Info> V[100000];
int min_time[100000];

int main(){

	int N,M;
	scanf("%d %d",&N,&M);

	int from,to,time;
	for(int i = 0; i < M; i++){
		scanf("%d %d %d",&from,&to,&time);
		from--;
		to--;
		V[from].push_back(Info(to,time));
	}

	for(int i = 0; i < N; i++)min_time[i] = BIG_NUM;

	min_time[0] = 0;

	priority_queue<Data> Q;
	Q.push(Data(0,0));

	int ans = -1;

	while(!Q.empty()){

		if(Q.top().current_time > min_time[Q.top().node_id]){
			Q.pop();
		}else{

			for(int i = 0; i < V[Q.top().node_id].size(); i++){
				if(Q.top().current_time > V[Q.top().node_id][i].time)continue;

				if(V[Q.top().node_id][i].to == N-1){
					ans = max(ans,V[Q.top().node_id][i].time);
				}else{
					if(min_time[V[Q.top().node_id][i].to] > V[Q.top().node_id][i].time){
						min_time[V[Q.top().node_id][i].to] = V[Q.top().node_id][i].time;
						Q.push(Data(V[Q.top().node_id][i].to,V[Q.top().node_id][i].time));
					}
				}
			}
			Q.pop();
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 9504
final_rank: 7

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	Info(int arg_to,int arg_time){
		to = arg_to;
		time = arg_time;
	}
	int to,time;
};

struct Data{
	Data(int arg_node_id,int arg_current_time){
		node_id = arg_node_id;
		current_time = arg_current_time;
	}
	bool operator<(const struct Data &arg) const{
		return current_time > arg.current_time;
	}
	int node_id,current_time;
};

vector<Info> V[100000];
int min_time[100000];

int main(){

	int N,M;
	scanf("%d %d",&N,&M);

	int from,to,time;
	for(int i = 0; i < M; i++){
		scanf("%d %d %d",&from,&to,&time);
		from--;
		to--;
		V[from].push_back(Info(to,time));
	}

	for(int i = 0; i < N; i++)min_time[i] = BIG_NUM;

	min_time[0] = 0;

	priority_queue<Data> Q;
	Q.push(Data(0,0));

	int ans = -1;

	while(!Q.empty()){

		if(Q.top().node_id == N-1){
			ans = max(ans,Q.top().current_time);
			Q.pop();
		}else if(Q.top().current_time > min_time[Q.top().node_id]){
			Q.pop();
		}else{

			for(int i = 0; i < V[Q.top().node_id].size(); i++){
				if(Q.top().current_time > V[Q.top().node_id][i].time)continue;

				if(min_time[V[Q.top().node_id][i].to] > V[Q.top().node_id][i].time){
					min_time[V[Q.top().node_id][i].to] = V[Q.top().node_id][i].time;
					Q.push(Data(V[Q.top().node_id][i].to,V[Q.top().node_id][i].time));
				}else if(V[Q.top().node_id][i].to == N-1){
					Q.push(Data(V[Q.top().node_id][i].to,V[Q.top().node_id][i].time));
				}
			}
			Q.pop();
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 9504
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 100000
struct edge{ int to,cost; };
typedef pair<int,int> P;
const int INF=1000000001;
 
int N,M;
int d[MAX_N];
vector<edge> G[MAX_N];
 
int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    G[a].push_back((edge){b,c});
  }
  int ans=-1;  
  priority_queue< P , vector<P> , greater<P> > Q;
  fill(d,d+MAX_N,INF);
  Q.push(P(1,1));
  d[1]=1;
  while(!Q.empty()){
    P p=Q.top();Q.pop();
    int pos=p.second;
    int cost=p.first;
    if(d[pos]<cost)continue;
    for(int i=0;i<(int)G[pos].size();i++){
      edge e=G[pos][i];
      if(e.cost<d[pos])continue;
      if(e.to==N)ans=max(ans,e.cost);
      if(d[e.to]>e.cost){
        d[e.to]=e.cost;
        Q.push(P(d[e.to],e.to));
      }
    }
  }
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 9564
final_rank: 8

code_snippet: #include <cstdio>
#include <climits>
#include <vector>
#include <queue>

constexpr int MAX_N = 100000;
constexpr int INF = INT_MAX;

template<class T>
using vec = std::vector<T>;

struct Edge {
    int to, age;
    Edge (int to, int age) : to{to}, age{age} {}
};

struct State {
    int c, v;
    State (int c, int v) : c{c}, v{v} {}

    bool operator < (const State &s) const {
        return c > s.c;
    }
};

int main()
{
    int N, M, a, b, c;
    scanf("%d %d", &N, &M);
    
    vec<Edge> G[MAX_N];
    for (int i = 0; i < M; i++) {
        scanf("%d %d %d", &a, &b, &c); a--; b--;
        G[a].push_back(Edge(b, c));
    }
    
    vec<int> d(MAX_N + 1, INF);
    d[0] = 1;

    std::priority_queue<State> pq;
    pq.push(State(1, 0));
    int res = -1;
    
    while (!pq.empty()) {
        State s = pq.top(); pq.pop();
        if (s.v == N - 1 || d[s.v] < s.c) continue;
        
        for (Edge &e : G[s.v]) {
            if (d[s.v] > e.age) continue;
            if (e.to == N - 1) {
                res = std::max(res, e.age);
            }
                
            if (e.age < d[e.to]) {
                d[e.to] = e.age;
                pq.push(State(d[e.to], e.to));
            }
        }
    }
    
    printf("%d\n", res);
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 9100
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_N 100000
struct edge{ int to,cost; };
typedef pair<int,int> P;
const int INF=1000000001;

int N,M;
int d[MAX_N];
vector<edge> G[MAX_N];

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    int a,b,c;
    scanf("%d %d %d",&a,&b,&c);
    G[a].push_back((edge){b,c});
  }
  int ans=-1;  
  priority_queue< P , vector<P> , greater<P> > Q;
  fill(d,d+MAX_N,INF);
  Q.push(P(1,1));
  d[1]=1;
  while(!Q.empty()){
    P p=Q.top();Q.pop();
    int pos=p.second;
    int cost=p.first;
    if(d[pos]<cost)continue;
    for(int i=0;i<(int)G[pos].size();i++){
      edge e=G[pos][i];
      if(e.cost<d[pos])continue;
      if(e.to==N)ans=max(ans,e.cost);
      if(d[e.to]>e.cost){
        d[e.to]=e.cost;
        Q.push(P(d[e.to],e.to));
      }
    }
  }
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 9660
final_rank: 9