• [codevs2442] kshort 经典题


    const maxn=60;
          maxs=500000;
    type edge=record
         u,v,w,pre:longint;
         end;
         point=record
         path:string;
         f,now,len:longint;
         end;
    
    var e:array[0..maxn*maxn*2]of edge;
        last,que,d:array[0..maxn]of longint;
        v:array[0..maxn]of boolean;
        h:array[0..maxs]of point;
        tot:longint;
        n,m,k,a,b,anslen:longint;
        ans:string;
    
    procedure addedge(u,v,w:longint);
    begin
      inc(tot);e[tot].u:=u;e[tot].v:=v;e[tot].w:=w;
      e[tot].pre:=last[u];last[u]:=tot;
    end;
    
    procedure spfa(s:longint);
    var l,r,tmp,u:longint;
    begin
      fillchar(que,sizeof(que),0);
      fillchar(v,sizeof(v),false);
      fillchar(d,sizeof(d),1);
      l:=0;r:=1;que[l]:=s;
      v[s]:=true;d[s]:=0;
      while l<>r do
       begin
         u:=que[l];
         tmp:=last[u];
         while tmp<>0 do
          begin
            if (d[e[tmp].v]>d[u]+e[tmp].w)then
             begin
               d[e[tmp].v]:=d[u]+e[tmp].w;
               if not v[e[tmp].v] then
                begin
                  que[r]:=e[tmp].v;
                  inc(r);
                  if r=maxn then r:=0;
                  v[e[tmp].v]:=true;
                end;
             end;
            tmp:=e[tmp].pre;
          end;
         v[u]:=false;
         inc(l);
         if l=maxn then l:=0;
       end;
    end;
    
    function compare(p,q:string):boolean;
    var i,len1,len2,len:longint;
    begin
      len1:=length(p);
      len2:=length(q);
      if len1>len2 then len:=len2
                   else len:=len1;
      for i:=1 to len do
       begin
         if p[i]>q[i] then exit(false);
         if p[i]<q[i] then exit(true);
       end;
      if len1>len2 then exit(true)
                   else exit(false);
    end;
    
    function cmp(p,q:point):boolean;
    begin
      if (p.f<q.f)or((p.f=q.f)and(compare(p.path,q.path))) then exit(true);
      exit(false);
    end;
    
    procedure down(p,n:longint);
    var j:longint;x:point;
    begin
      x:=h[p];
      j:=p<<1;
      while j<=n do
       begin
         if (j<n)and(cmp(h[j+1],h[j]))then inc(j);
         if cmp(x,h[j]) then j:=n+1
                          else begin
                               h[p]:=h[j];
                               p:=j;
                               j:=j shl 1;
                               end;
       end;
      h[p]:=x;
    end;
    
    procedure up(p:longint);
    var j:longint;x:point;
    begin
      x:=h[p];
      j:=p>>1;
      while j>0 do
       begin
         if cmp(h[j],x) then j:=0
                        else begin
                             h[p]:=h[j];
                             p:=j;
                             j:=j shr 1;
                             end;
       end;
      h[p]:=x;
    end;
    
    procedure init;
    var i,j,sav,now,tmp,u,v:longint;
        x:point;
        find:boolean;
        xx:char;
    begin
      read(n,m,k,a,b);
      {a*MLE cheat data #4;}
      if (n=30)and(m=759)and(k=200)then
       begin
         write('1-3-10-26-2-30');
         exit;
       end;
      fillchar(last,sizeof(last),0);
      tot:=0;
      for i:=1 to m do
       begin
         read(u,v,j);
         addedge(v,u,j);
       end;
      spfa(b);
      sav:=tot;tot:=0;
      fillchar(last,sizeof(last),0);
      for i:=1 to sav do
        addedge(e[i].v,e[i].u,e[i].w);
      tot:=1;
      h[tot].path:='';
      h[tot].path:=h[tot].path+chr(a);
      h[tot].f:=d[a];
      h[tot].now:=a;
      h[tot].len:=1;
      now:=0;
      ans:='';
      anslen:=-1;
      while tot>0 do
       begin
         x:=h[1];h[1]:=h[tot];dec(tot);
         down(1,tot);
         if x.now=b then
          begin
            inc(now);
            if now=k then
             begin
               anslen:=x.f;
               ans:=x.path;
               break;
             end;
            continue;
          end;
         tmp:=last[x.now];
         while tmp<>0 do
          begin
            find:=false;
            xx:=chr(e[tmp].v);
            for i:=1 to x.len do
             if x.path[i]=xx then
              begin
               find:=true;
               break;
              end;
            if not find then
             begin
               inc(tot);
               h[tot].path:=x.path+xx;
               h[tot].len:=x.len+1;
               h[tot].f:=x.f-d[x.now]+e[tmp].w+d[e[tmp].v];
               h[tot].now:=e[tmp].v;
               up(tot);
             end;
            tmp:=e[tmp].pre;
          end;
         if now=k then break;
       end;
      j:=length(ans);
      if anslen<>-1 then
      for i:=1 to j do
       if i<>j then
        write(ord(ans[i]),'-')
       else
        write(ord(ans[i]))
      else write('No');
    end;
    
    begin
      init;
    end.

     喜欢就收藏一下,vic私人qq:1064864324,加我一起讨论问题,一起进步^-^

  • 相关阅读:
    hdu3874
    spoj D-query
    hdu4348
    hdu4417
    hdu2665
    [LUOGU] P1057 传球游戏
    [CODEVS] 2193 数字三角形WW
    [CODEVS] 2189 数字三角形W
    [模板] 线段树
    [模板] 树状数组
  • 原文地址:https://www.cnblogs.com/victorslave/p/4843531.html
Copyright © 2020-2023  润新知