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
     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

Please read the guidelines before commenting.


There are no comments at the moment.