Hướng dẫn giải của Revamping Trails


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

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.

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.