• bzoj2763


    首先是稀疏图,不难想到dij+heap

    观察题目可以知道,0<=k<=10;

    所以比较裸的想法就是,d[i,j]表示已经免费了i条线路后到达j的最短路

    容易得到

    d[i,j]:=min(d[i,j],d[i-1,k]);

    d[i,j]:=min(d[i,j],d[i,k]+w[k,j]);

    然后在做dij在选择中间点的时候,我们穷举一下免费的线路数就可以了;

    然后就要维护10个堆……

    语言表述有点渣,具体还是看程序吧

      1 const inf=2000000007;
      2 type point=record
      3        num,dis:longint;
      4      end;
      5      node=record
      6        next,cost,point:longint;
      7      end;
      8 
      9 var edge:array[0..200010] of node;
     10     heap:array[0..11,0..10010] of point;
     11     d,where:array[0..11,0..10010] of longint;
     12     h:array[0..11] of longint;
     13     p:array[0..10010] of longint;
     14     len,x,y,z,i,j,n,m,u,k,s,t:longint;
     15 
     16 procedure swap(var a,b:point);
     17   var c:point;
     18   begin
     19     c:=a;
     20     a:=b;
     21     b:=c;
     22   end;
     23 
     24 function min(a,b:longint):longint;
     25   begin
     26     if a>b then exit(b) else exit(a);
     27   end;
     28 
     29 procedure add(x,y,z:longint);
     30   begin
     31     inc(len);
     32     edge[len].point:=y;
     33     edge[len].cost:=z;
     34     edge[len].next:=p[x];
     35     p[x]:=len;
     36   end;
     37 
     38 procedure sift(p,i:longint);
     39   var j,x,y:longint;
     40   begin
     41     j:=i shl 1;
     42     while j<=h[p] do
     43     begin
     44       if (j+1<=h[p]) and (heap[p,j].dis>heap[p,j+1].dis) then inc(j);
     45       if heap[p,i].dis>heap[p,j].dis then
     46       begin
     47         x:=heap[p,i].num;
     48         y:=heap[p,j].num;
     49         where[p,x]:=j;
     50         where[p,y]:=i;
     51         swap(heap[p,i],heap[p,j]);
     52         i:=j;
     53         j:=i shl 1;
     54       end
     55       else break;
     56     end;
     57   end;
     58 
     59 procedure up(p,i:longint);
     60   var j,x,y:longint;
     61   begin
     62     j:=i shr 1;
     63     while j>0 do
     64     begin
     65       if heap[p,i].dis<heap[p,j].dis then
     66       begin
     67         x:=heap[p,i].num;
     68         y:=heap[p,j].num;
     69         where[p,x]:=j;
     70         where[p,y]:=i;
     71         swap(heap[p,i],heap[p,j]);
     72         i:=j;
     73         j:=j shr 1;
     74       end
     75       else break;
     76     end;
     77   end;
     78 
     79 begin
     80   len:=-1;
     81   fillchar(p,sizeof(p),255);
     82   readln(n,m,k);
     83   readln(s,t);
     84   inc(s);  //点序号都+1,习惯一点
     85   inc(t);
     86   for i:=1 to m do
     87   begin
     88     readln(x,y,z);
     89     inc(x);
     90     inc(y);
     91     add(x,y,z);
     92     add(y,x,z);
     93   end;
     94   for i:=1 to n do
     95     if i<>s then
     96     begin
     97       for j:=0 to k do
     98         d[j,i]:=inf;
     99     end
    100     else
    101       for j:=0 to k do
    102         d[j,i]:=0;
    103   for i:=0 to k do
    104   begin
    105     for j:=1 to n do
    106     begin
    107       heap[i,j].num:=j;
    108       heap[i,j].dis:=d[i,j];
    109       where[i,j]:=j;
    110     end;
    111     h[i]:=n;
    112   end;
    113   for i:=0 to k do
    114     up(i,s);  //起点不一定是0,要初始化堆,一开始这里被坑翻了
    115   for u:=1 to n do
    116   begin
    117     for j:=k downto 0 do 
    118     begin
    119       x:=heap[j,1].num;
    120       y:=heap[j,h[j]].num;  
    121       if (h[j]=0) or (d[j,x]=inf) then continue;
    122       where[j,y]:=1;  //dij+heap比较重要的细节
    123       swap(heap[j,1],heap[j,h[j]]);
    124       dec(h[j]); 
    125       sift(j,1);  //出堆,调整堆
    126       i:=p[x];
    127       while i<>-1 do
    128       begin
    129         y:=edge[i].point;
    130         if (j<>k) and (d[j+1,y]>d[j,x]) then   //两种情况
    131         begin
    132           d[j+1,y]:=d[j,x];
    133           heap[j+1,where[j+1,y]].dis:=d[j+1,y];
    134           up(j+1,where[j+1,y]);
    135         end;
    136         if (d[j,y]>d[j,x]+edge[i].cost) then
    137         begin
    138           d[j,y]:=d[j,x]+edge[i].cost;
    139           heap[j,where[j,y]].dis:=d[j,y];
    140           up(j,where[j,y]);
    141         end;
    142         i:=edge[i].next;
    143       end;
    144     end;
    145   end;
    146   writeln(d[k,t]); //肯定尽可能免费好啊
    147 end.
    View Code
  • 相关阅读:
    JVM运行时数据区--堆
    ES检索服务搜索结果高亮
    SpringBoot 设置编码UTF-8
    response.setContentType()的作用及参数
    将 vue.js 获取的 html 文本转化为纯文本
    SpringBoot读取properties文件配置项
    关于Java的编译执行与解释执行
    Java沙箱安全机制介绍【转载】
    JVM运行时数据区--本地方法栈
    JVM--先说本地方法接口
  • 原文地址:https://www.cnblogs.com/phile/p/4473218.html
Copyright © 2020-2023  润新知