## Editorial for Revamping Trails

Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

#### Code mẫu của flashmt

const maxm=50100;
maxn=10100;
var n,m,k,nh:longint;
pos,sl,cur:array[1..maxn] of longint;
a,v:array[1..maxm*2] of longint;
b,c,e:array[1..maxm] of longint;
d:array[0..20,1..maxn] of boolean;
p:array[0..20,1..maxn] of longint;
f:array[0..20,1..maxn] of int64;
h,g:array[1..22*maxn] of longint;
oo:int64;

procedure rf;
var i,j:longint;
begin
for i:=1 to m do
begin
inc(sl[b[i]]);
inc(sl[c[i]]);
end;
pos[1]:=1; cur[1]:=1;
for i:=2 to n+1 do
begin
pos[i]:=pos[i-1]+sl[i-1];
cur[i]:=pos[i];
end;
for i:=1 to m do
begin
a[cur[b[i]]]:=c[i];
v[cur[b[i]]]:=e[i];
inc(cur[b[i]]);
a[cur[c[i]]]:=b[i];
v[cur[c[i]]]:=e[i];
inc(cur[c[i]]);
end;
end;

procedure init;
var i,j:longint;
begin
oo:=1000000000;
oo:=oo*oo;
for i:=0 to k do
for j:=1 to n do
f[i,j]:=oo;
nh:=0;
end;

procedure update(x,y:longint);
var cha,con:longint;
begin
con:=p[x,y];
if con=0 then
begin
nh:=nh+1;
con:=nh;
end;
cha:=con shr 1;
while (cha>0) and (f[g[cha],h[cha]]>f[x,y]) do
begin
h[con]:=h[cha];
g[con]:=g[cha];
p[g[con],h[con]]:=con;
con:=cha;
cha:=con shr 1;
end;
h[con]:=y; g[con]:=x;
p[x,y]:=con;
end;

procedure pop(var xx,yy:longint);
var x,y,cha,con:longint;
begin
xx:=g[1]; yy:=h[1];
x:=g[nh]; y:=h[nh];
nh:=nh-1;
cha:=1; con:=2;
while con<=nh do
begin
if (con<nh) and (f[g[con+1],h[con+1]]<f[g[con],h[con]]) then con:=con+1;
if f[x,y]<=f[g[con],h[con]] then break;
h[cha]:=h[con];
g[cha]:=g[con];
p[g[cha],h[cha]]:=cha;
cha:=con;
con:=cha shl 1;
end;
h[cha]:=y; g[cha]:=x;
p[x,y]:=cha;
end;

procedure pr;
var i,j,x,y:longint;
begin
f[k,1]:=0;
for i:=0 to k-1 do d[i,1]:=true;
update(k,1);
repeat
pop(x,y);
d[x,y]:=true;
if y=n then
begin
writeln(f[x,y]);
exit;
end;
for i:=0 to x do
for j:=pos[y] to pos[y+1]-1 do
if not d[i,a[j]] and (f[i,a[j]]>f[x,y]+v[j]*ord(x=i)) then
begin
f[i,a[j]]:=f[x,y]+v[j]*ord(x=i);
update(i,a[j]);
end;
until false;
end;

begin
rf;
init;
pr;
end.


{$MODE OBJFPC} program REVAMP; uses math; const maxn=10001; maxm=100005; maxk=21; oo=trunc(1e9); fi=''; fo=''; type e =record v,w,link:longint; end; xy=record x,y:longint; end; var n,m,k,nh,mm:longint; adj:array[1..maxm] of e; head:array[1..maxn] of longint; pos,d:array[1..maxn,0..maxk] of longint; h:array[1..maxn*maxk] of xy; procedure input; var inp:text; i,x,y,w:longint; begin assign(inp,fi);reset(inp); readln(inp,n,mm,k); for i:=1 to mm do begin readln(inp,x,y,w); inc(m); adj[m].v:=y; adj[m].w:=w; adj[m].link:=head[x]; head[x]:=m; inc(m); adj[m].v:=x; adj[m].w:=w; adj[m].link:=head[y]; head[y]:=m; end; close(inp); end; procedure update(i,j:longint); var p,c:longint; begin c:=pos[i,j]; if c=0 then begin inc(nh); c:=nh; end; repeat p:=c div 2; if (p=0) or (d[h[p].x,h[p].y]<=d[i,j]) then break; h[c]:=h[p]; pos[h[c].x,h[c].y]:=c; c:=p; until false; h[c].x:=i;h[c].y:=j; pos[i,j]:=c; end; function extract:xy; var p,c:longint; v:xy; begin result:=h[1]; v:=h[nh]; dec(nh); p:=1; repeat c:=2*p; if (c<nh) and (d[h[c+1].x,h[c+1].y]<d[h[c].x,h[c].y]) then inc(c); if (c>nh) or (d[h[c].x,h[c].y]>=d[v.x,v.y]) then break; h[p]:=h[c]; pos[h[p].x,h[p].y]:=p; p:=c; until false; h[p]:=v; pos[v.x,v.y]:=p; end; procedure dijkstra; var i,j:longint; v:e; u:xy; begin for i:=1 to n do for j:=0 to k do d[i,j]:=oo; d[1,0]:=0; update(1,0); repeat u:=extract; i:=head[u.x]; while i>0 do begin v:=adj[i]; if d[v.v,u.y]>d[u.x,u.y]+v.w then begin d[v.v,u.y]:=d[u.x,u.y]+v.w; update(v.v,u.y); end; if u.y<k then if d[v.v,u.y+1]>d[u.x,u.y] then begin d[v.v,u.y+1]:=d[u.x,u.y]; update(v.v,u.y+1); end; i:=v.link; end; until nh=0; end; procedure output; var i,res:longint; begin res:=oo; for i:=1 to k do res:=min(res,d[n,i]); write(res); end; begin input; dijkstra; output; end.  #### Code mẫu của RR { ID: invinci3 PROG: revamp LANG: PASCAL } {$R+,Q+}
uses math;
const
FINP='';
FOUT='';
MAXN=10001;
oo=1000000001;
type
list=^node;
node=record
u,c:longint;
next:list;
end;
var
f1,f2:text;
k,hsize,n:longint;
ke:array[1..MAXN] of list;
hpos,d:array[1..MAXN,0..20] of longint;
hu,hv:array[1..MAXN*20] of longint;
procedure openF;
begin
assign(f1,FINP); reset(f1);
assign(f2,FOUT); rewrite(f2);
end;
procedure closeF;
begin
close(f1); close(f2);
end;
var
p:list;
begin
new(p); p^.u:=u; p^.c:=c;
p^.next:=a; a:=p;
end;
procedure inp;
var
i,u,v,c,m:longint;
begin
for i:=1 to m do
begin
end;
end;
procedure swap(var a,b:longint); inline;
var
temp:longint;
begin
temp:=a; a:=b; b:=temp;
end;
procedure downHeap(i:longint);
var
j:longint;
begin
j:=i<<1;
while (j<=hsize) do
begin
if (j<hsize) and (d[hu[j+1],hv[j+1]]<d[hu[j],hv[j]]) then inc(j);
if (d[hu[i],hv[i]]>d[hu[j],hv[j]]) then
begin
swap(hpos[hu[i],hv[i]],hpos[hu[j],hv[j]]);
swap(hu[i],hu[j]);
swap(hv[i],hv[j]);
end;
i:=j; j:=i<<1;
end;
end;
procedure upHeap(i:longint);
var
j:longint;
begin
j:=i>>1;
while (i>1) and (d[hu[i],hv[i]]<d[hu[j],hv[j]]) do
begin
swap(hpos[hu[i],hv[i]],hpos[hu[j],hv[j]]);
swap(hu[i],hu[j]);
swap(hv[i],hv[j]);
i:=j; j:=i>>1;
end;
end;
procedure push(u,v:longint);
begin
inc(hsize); hu[hsize]:=u; hv[hsize]:=v; hpos[u,v]:=hsize;
upHeap(hsize);
end;
procedure pop(var u,v:longint);
begin
u:=hu[1]; v:=hv[1]; hpos[u,v]:=0;
swap(hu[1],hu[hsize]); swap(hv[1],hv[hsize]); hpos[hu[1],hv[1]]:=1;
dec(hsize); downHeap(1);
end;
procedure solve;
var
u,v,c,uu,vv:longint;
p:list;
begin
hsize:=0;
for u:=1 to n do for v:=0 to k do d[u,v]:=oo;
d[1,0]:=0;
push(1,0);
while hsize>0 do
begin
pop(u,v);
if u=n then
begin
writeln(f2,d[u,v]);
exit;
end;
p:=ke[u];
while p<>nil do
begin
uu:=p^.u; c:=p^.c; p:=p^.next;
//Thay canh (u,v) = 0
if v<k then
if d[uu,v+1]>d[u,v] then
begin
d[uu,v+1]:=d[u,v];
if hpos[uu,v+1]=0 then push(uu,v+1)
else upHeap(hpos[uu,v+1]);
end;
//Di qua canh (u,v)
if d[uu,v]>d[u,v]+c then
begin
d[uu,v]:=d[u,v]+c;
if hpos[uu,v]=0 then push(uu,v)
else upHeap(hpos[uu,v]);
end;
end;
end;
end;
begin
openF;
inp;
solve;
closeF;
end.


#### Code mẫu của hieult

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <ctime>
#include <deque>
#include <bitset>
#include <cctype>
#include <utility>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

#define Rep(i,n) for(int i = 0; i < (n); ++i)
#define Repd(i,n) for(int i = (n)-1; i >= 0; --i)
#define For(i,a,b) for(int i = (a); i <= (b); ++i)
#define Ford(i,a,b) for(int i = (a); i >= (b); --i)
#define Fit(i,v) for(__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++i)
#define Fitd(i,v) for(__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++i)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(a) ((int)(a).size())
#define all(a) (a).begin(), (a).end()
#define ms(a,x) memset(a, x, sizeof(a))

template<class F, class T> T convert(F a, int p = -1) {
stringstream ss;
if (p >= 0)
ss << fixed << setprecision(p);
ss << a;
T r;
ss >> r;
return r;
}
template<class T> T gcd(T a, T b) {
T r;
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
template<class T> T lcm(T a, T b) {
return a / gcd(a, b) * b;
}
template<class T> T sqr(T x) {
return x * x;
}
template<class T> T cube(T x) {
return x * x * x;
}
template<class T> int getbit(T s, int i) {
return (s >> i) & 1;
}
template<class T> T onbit(T s, int i) {
return s | (T(1) << i);
}
template<class T> T offbit(T s, int i) {
return s & (~(T(1) << i));
}
template<class T> int cntbit(T s) {
return s == 0 ? 0 : cntbit(s >> 1) + (s & 1);
}

const int bfsz = 1 << 16;
char bf[bfsz + 5];
int rsz = 0;
int ptr = 0;
char gc() {
if (rsz <= 0) {
ptr = 0;
rsz = (int) fread(bf, 1, bfsz, stdin);
if (rsz <= 0)
return EOF;
}
--rsz;
return bf[ptr++];
}
void ga(char &c) {
c = EOF;
while (!isalpha(c))
c = gc();
}
int gs(char s[]) {
int l = 0;
char c = gc();
while (isspace(c))
c = gc();
while (c != EOF && !isspace(c)) {
s[l++] = c;
c = gc();
}
s[l] = '\0';
return l;
}
template<class T> bool gi(T &v) {
v = 0;
char c = gc();
while (c != EOF && c != '-' && !isdigit(c))
c = gc();
if (c == EOF)
return false;
bool neg = c == '-';
if (neg)
c = gc();
while (isdigit(c)) {
v = v * 10 + c - '0';
c = gc();
}
if (neg)
v = -v;
return true;
}

typedef pair<int, int> II;
const ld PI = acos(-1.0);
const ld eps = 1e-9;
const int dr[] = { -1, 0, +1, 0};
const int dc[] = { 0, +1, 0, -1};
const int inf = (int) 1e9 + 5;
const ll linf = (ll) 1e16 + 5;
const int mod = (ll) (1e9 + eps);
#define ok puts("ok")
#define maxn 20005
#define maxe 200005

int n, m, k;
int adj[maxe], next[maxe], last[maxn], cost[maxe], E = 0;
ll f[maxn][22];

void add(int u, int v, int c){
adj[E] = v; cost[E] = c; next[E] = last[u]; last[u] = E++;
adj[E] = u; cost[E] = c; next[E] = last[v]; last[v] = E++;
}

int main(){
//  freopen("in.txt", "r", stdin);
scanf("%d %d %d", &n, &m, &k);
int u, v, c, num;
ms(last, -1); E = 0;
Rep(run, m){
scanf("%d %d %d", &u, &v, &c);
}

ms(f, 0x3f);
For(i, 0, k) f[1][i] = 0;
priority_queue<pair<ll, II> > que;
que.push(mp(0, mp(1, 0)));
ll C, res = linf;

while(!que.empty()){
C = -que.top().fi; u = que.top().se.fi; num = que.top().se.se; que.pop();
if(f[u][num] < C) continue;
if(u == n){
res = f[n][num];
break;
}
for(int e = last[u]; e != -1; e = next[e]){
if(f[v][num] > C + cost[e]){
f[v][num] = C + cost[e];
que.push(mp(-f[v][num], mp(v, num)));
}

if(num < k && f[v][num + 1] > C){
f[v][num + 1] = C;
que.push(mp(-f[v][num + 1], mp(v, num + 1)));
}
}
}

cout << res;

return 0;
}


{$MODE DELPHI} Program REVAMP; Const input = ''; output = ''; maxn = 10000; maxm = 50000; maxk = 20; maxc = 1000000000; Type rec = record x,y: integer; end; Var n,m,k: integer; u,modi: integer; nHeap: integer; p,q,c: array[1..maxm] of integer; heap: array[1..300000] of rec; adj,adjcost: array[1..2 * maxm] of integer; h: array[1..maxn + 1] of integer; d,pos: array[1..maxn,0..maxk] of integer; free: array[1..maxn,0..maxk] of boolean; Procedure init; Var f: text; i: integer; Begin Fillchar(h, sizeof(h), 0); Assign(f, input); Reset(f); Readln(f, n, m, k); For i:= 1 to m do Begin Readln(f, p[i], q[i], c[i]); inc(h[p[i]]); inc(h[q[i]]); End; Close(f); For i:= 2 to n do h[i]:= h[i] + h[i - 1]; For i:= 1 to m do Begin adj[h[p[i]]]:= q[i]; adjcost[h[p[i]]]:= c[i]; dec(h[p[i]]); adj[h[q[i]]]:= p[i]; adjcost[h[q[i]]]:= c[i]; dec(h[q[i]]); End; h[n + 1]:= 2 * m; End; Procedure update(u,v: integer); Var parent,child: integer; Begin child:= pos[u,v]; If child = 0 then Begin inc(nHeap); child:= nHeap; End; parent:= child div 2; While (parent > 0) and (d[heap[parent].x,heap[parent].y] > d[u,v]) do Begin heap[child]:= heap[parent]; pos[heap[child].x,heap[child].y]:= child; child:= parent; parent:= child div 2; End; heap[child].x:= u; heap[child].y:= v; pos[u,v]:= child; End; Procedure pop; Var r,s,popx,popy: integer; Begin u:= heap[1].x; modi:= heap[1].y; popx:= heap[nHeap].x; popy:= heap[nHeap].y; dec(nHeap); r:= 1; While r * 2 <= nHeap do Begin s:= r * 2; If (s < nHeap) and (d[heap[s + 1].x,heap[s + 1].y] < d[heap[s].x,heap[s].y]) then inc(s); If d[popx,popy] <= d[heap[s].x,heap[s].y] then break; heap[r]:= heap[s]; pos[heap[r].x,heap[r].y]:= r; r:= s; End; heap[r].x:= popx; heap[r].y:= popy; pos[popx,popy]:= r; End; Procedure Dijkstra; Var i,j,v,iv: integer; Begin Fillchar(pos, sizeof(pos), 0); nHeap:= 0; Fillchar(free, sizeof(free), true); For i:= 1 to n do For j:= 0 to k do d[i,j]:= maxc; d[1,0]:= 0; update(1,0); Repeat pop; free[u,modi]:= false; For iv:= h[u] + 1 to h[u + 1] do Begin v:= adj[iv]; If free[v,modi] and (d[v,modi] > d[u,modi] + adjcost[iv]) then Begin d[v,modi]:= d[u,modi] + adjcost[iv]; update(v,modi); End; If modi < k then If free[v,modi + 1] and (d[v,modi + 1] > d[u,modi]) then Begin d[v,modi + 1]:= d[u,modi]; update(v,modi + 1); End; End; Until nHeap = 0; End; Procedure printresult; Var f: text; Begin Assign(f, output); Rewrite(f); Writeln(f, d[n,k]); Close(f); End; Begin init; Dijkstra; printresult; End.  #### Code mẫu của khuc_tuan // {$APPTYPE CONSOLE}
{$mode delphi} type List = class v, l : integer; n : List; end; procedure Add(var ds : List; v, l : integer);overload; var p : List; begin p := List.Create; p.v := v; p.l := l; p.n := ds; ds := p; end; var m, n, k : integer; ke : array[1..50000] of List; heap, id, d : array[1..1050020] of integer; nh : integer; procedure pushup(i : integer); var t, j : integer; begin while i>=2 do begin j := i div 2; if d[heap[j]] > d[heap[i]] then begin t := heap[i]; heap[i] := heap[j]; heap[j] := t; id[heap[i]] := i; id[heap[j]] := j; i := j; end else break; end; end; procedure pushdown(i : integer); var t, j : integer; begin while i*2 <= nh do begin j := i * 2; if (j<nh) and (d[heap[j+1]] < d[heap[j]]) then inc(j); if d[heap[j]] < d[heap[i]] then begin t := heap[i]; heap[i] := heap[j]; heap[j] := t; id[heap[i]] := i; id[heap[j]] := j; i := j; end else break; end; end; function extractmin : integer; begin extractmin := heap[1]; id[heap[1]] := 0; dec(nh); if nh > 0 then begin heap[1] := heap[nh+1]; id[heap[1]] := 1; pushdown(1); end; end; procedure add(i : integer);overload; begin inc(nh); heap[nh] := i; id[i] := nh; pushup(nh); end; var l, i, su, sv : integer; res, u, uk, v, vk : integer; p : List; begin read(n,m,k); for i:=1 to m do begin read(u,v,l); Add(ke[u], v, l); Add(ke[v], u, l); end; fillchar( d, sizeof(d),$1f);
res := d[1];
d[1 * 21 + 0] := 0;
add( 1 * 21 + 0 );
while nh > 0 do
begin
su := extractmin;
u := su div 21;
uk := su mod 21;
p := ke[u];
while p<>nil do
begin
// khong xoa
v := p.v;
vk := uk;
sv := v * 21 + vk;
if d[sv] > d[su] + p.l then
begin
d[sv] := d[su] + p.l;
else
begin
l := id[sv];
pushup(l);
pushdown(l);
end;
end;

// xoa
vk := uk + 1;
if vk <= k then
begin
sv := v * 21 + vk;
if d[sv] > d[su] then
begin
d[sv] := d[su];
else
begin
l := id[sv];
pushup(l);
pushdown(l);
end;
end;
end;

p := p.n;
end;
end;
for i:=0 to k do if res > d[n * 21 + i] then res := d[n * 21 + i];
writeln(res);
end.