#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue> #include <vector> #include <map> #include <set> #include <string> using namespace std; //---------------------------------------------- #define CL(a,num) memset(a,num,sizeof(a)); #define BtoA(x,y) memcpy(x,y,sizeof(x)); #define eps 1e-12 #define inf 0x7fffffff typedef __int64 LL; //---------------------------------------------- const int Nmax = 1000 + 5; struct Edge {int from, to, dis;}; struct HeapNode { int d, idx; bool operator < (const HeapNode& rhs) const { return d > rhs.d; } }; struct Dijk { int n, m; vector<Edge> edges; vector<int> G[Nmax]; bool vis[Nmax]; int d[Nmax]; int p[Nmax]; void init(int n) { this->n = n; for(int i = 1; i <= n; ++i) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int dis) { edges.push_back((Edge){from, to, dis}); m = edges.size(); G[from].push_back(m-1); // } void dijk(int s) { priority_queue<HeapNode> q; for(int i = 1; i <= n; ++i) d[i] = inf; d[s] = 0; CL(vis, 0); q.push((HeapNode){0, s}); while(!q.empty()) { HeapNode x = q.top(); q.pop(); int idx = x.idx; if(vis[idx]) continue; vis[idx] = true; for(int i = 0; i < G[idx].size(); ++i) { Edge& e = edges[G[idx][i]]; if(d[e.to] > d[idx] + e.dis) { d[e.to] = d[idx] + e.dis; p[e.to] = G[idx][i]; q.push((HeapNode){d[e.to], e.to}); } } } } void Get_SP(int s, int* dis, vector<int>* path) { //Get_Shortest_Path dijk(s); for(int i = 1; i <= n; ++i) { dis[i] = d[i]; path[i].clear(); int t = i; path[i].push_back(t); while(t != s) { path[i].push_back(edges[p[t]].from); t = edges[p[t]].from; } reverse(path[i].begin(), path[i].end()); } } }; int N, M, ans; Dijk solver; int d[Nmax]; vector<int> path[Nmax]; int main() { freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); cin >> N >> M; solver.init(N); for(int i = 1; i <= M; ++i) { int s, t, d; cin >> s >> t >> d; solver.AddEdge(s, t, d); } solver.Get_SP(1, d, path); ans = d[N]; cout << ans << endl; return 0; }