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.
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 read(n,m,k); for i:=1 to m do begin read(b[i],c[i],e[i]); 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.
Code mẫu của ladpro98
{$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; procedure add(u,c:longint; var a:list); inline; 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 read(f1,n,m,k); for i:=1 to m do begin read(f1,u,v,c); add(u,c,ke[v]); add(v,c,ke[u]); 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); add(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]){ v = adj[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; }
Code mẫu của ll931110
{$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; if id[sv]=0 then add(sv) 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]; if id[sv]=0 then add(sv) 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.
Comments