- k-th shortest pathという有名問題です
- Spaghetti Sourceのライブラリを使用しています
static const int INF = INT_MAX / 2;
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef int Weight;
struct Edge {
int src, dst;
Weight weight;
Edge(int src, int dst, Weight weight) :
src(src), dst(dst), weight(weight) { }
};
bool operator < (const Edge &e, const Edge &f) {
return e.weight != f.weight ? e.weight > f.weight :
e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
Weight k_shortestPath(const Graph &g, int s, int t, int k) {
const int n = g.size();
Graph h(n);
REP(u, n) {
for (Edges::const_iterator e = g[u].begin(); e != g[u].end(); ++e) {
h[e->dst].push_back(Edge(e->dst,e->src,e->weight));
}
}
vector<Weight> d(n, INF); d[t] = 0;
vector<int> p(n, -1);
priority_queue<Edge> Q; Q.push(Edge(t, t, 0));
while (!Q.empty()) {
Edge e = Q.top(); Q.pop();
if (p[e.dst] >= 0) continue;
p[e.dst] = e.src;
for (Edges::iterator f = h[e.dst].begin(); f != h[e.dst].end(); ++f) {
if (d[f->dst] > e.weight + f->weight) {
d[f->dst] = e.weight + f->weight;
Q.push(Edge(f->src, f->dst, e.weight + f->weight));
}
}
}
int l = 0;
priority_queue<Edge> R; R.push(Edge(-1,s,0));
while (!R.empty()) {
Edge e = R.top(); R.pop();
if (e.dst == t && ++l == k) return e.weight + d[s];
for (Edges::const_iterator f = g[e.dst].begin(); f != g[e.dst].end(); ++f) {
R.push(Edge(f->src, f->dst, e.weight+f->weight-d[f->src]+d[f->dst]));
}
}
return -1;
}
int main()
{
int N, R;
cin >> N >> R;
Graph g(N + 1);
for (int i = 0; i < R; ++i) {
int A, B, D;
cin >> A >> B >> D;
g[A].push_back(Edge(A, B, D));
g[B].push_back(Edge(B, A, D));
}
cout << k_shortestPath(g, 1, N, 2) << endl;
}