首先是稀疏图,不难想到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个堆……

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

 const inf=;
type point=record
       num,dis:longint;
     end;
     node=record
       next,cost,point:longint;
     end; var edge:array[..] of node;
    heap:array[..,..] of point;
    d,where:array[..,..] of longint;
    h:array[..] of longint;
    p:array[..] of longint;
    len,x,y,z,i,j,n,m,u,k,s,t:longint; procedure swap(var a,b:point);
  var c:point;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; function min(a,b:longint):longint;
  begin
    if a>b then exit(b) else exit(a);
  end; procedure add(x,y,z:longint);
  begin
    inc(len);
    edge[len].point:=y;
    edge[len].cost:=z;
    edge[len].next:=p[x];
    p[x]:=len;
  end; procedure sift(p,i:longint);
  var j,x,y:longint;
  begin
    j:=i shl ;
    while j<=h[p] do
    begin
      if (j+<=h[p]) and (heap[p,j].dis>heap[p,j+].dis) then inc(j);
      if heap[p,i].dis>heap[p,j].dis then
      begin
        x:=heap[p,i].num;
        y:=heap[p,j].num;
        where[p,x]:=j;
        where[p,y]:=i;
        swap(heap[p,i],heap[p,j]);
        i:=j;
        j:=i shl ;
      end
      else break;
    end;
  end; procedure up(p,i:longint);
  var j,x,y:longint;
  begin
    j:=i shr ;
    while j> do
    begin
      if heap[p,i].dis<heap[p,j].dis then
      begin
        x:=heap[p,i].num;
        y:=heap[p,j].num;
        where[p,x]:=j;
        where[p,y]:=i;
        swap(heap[p,i],heap[p,j]);
        i:=j;
        j:=j shr ;
      end
      else break;
    end;
  end; begin
  len:=-;
  fillchar(p,sizeof(p),);
  readln(n,m,k);
  readln(s,t);
  inc(s);  //点序号都+,习惯一点
  inc(t);
  for i:= to m do
  begin
    readln(x,y,z);
    inc(x);
    inc(y);
    add(x,y,z);
    add(y,x,z);
  end;
  for i:= to n do
    if i<>s then
    begin
      for j:= to k do
        d[j,i]:=inf;
    end
    else
      for j:= to k do
        d[j,i]:=;
  for i:= to k do
  begin
    for j:= to n do
    begin
      heap[i,j].num:=j;
      heap[i,j].dis:=d[i,j];
      where[i,j]:=j;
    end;
    h[i]:=n;
  end;
  for i:= to k do
    up(i,s);  //起点不一定是0,要初始化堆,一开始这里被坑翻了
  for u:= to n do
  begin
    for j:=k downto do 
    begin
      x:=heap[j,].num;
      y:=heap[j,h[j]].num;  
      if (h[j]=) or (d[j,x]=inf) then continue;
      where[j,y]:=;  //dij+heap比较重要的细节
      swap(heap[j,],heap[j,h[j]]);
      dec(h[j]); 
      sift(j,);  //出堆,调整堆
      i:=p[x];
      while i<>- do
      begin
        y:=edge[i].point;
        if (j<>k) and (d[j+,y]>d[j,x]) then   //两种情况
        begin
          d[j+,y]:=d[j,x];
          heap[j+,where[j+,y]].dis:=d[j+,y];
          up(j+,where[j+,y]);
        end;
        if (d[j,y]>d[j,x]+edge[i].cost) then
        begin
          d[j,y]:=d[j,x]+edge[i].cost;
          heap[j,where[j,y]].dis:=d[j,y];
          up(j,where[j,y]);
        end;
        i:=edge[i].next;
      end;
    end;
  end;
  writeln(d[k,t]); //肯定尽可能免费好啊
end.

bzoj2763的更多相关文章

  1. BZOJ2763[JLOI2011]飞行路线 [分层图最短路]

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2523  Solved: 946[Submit][Statu ...

  2. 【BZOJ2763】飞行路线(最短路)

    [BZOJ2763]飞行路线(最短路) 题面 BZOJ Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标 ...

  3. BZOJ2763 JLOI2011 飞行路线 【最短路+DP】

    BZOJ2763 JLOI2011 飞行路线 Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n ...

  4. 【bzoj2763】[JLOI2011]飞行路线 (分层图最短路)(优先队列dij)

    [bzoj2763][JLOI2011]飞行路线 2014年3月25日1,7260 Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城 ...

  5. 分层图最短路【bzoj2763】: [JLOI2011]飞行路线

    bzoj2763: [JLOI2011]飞行路线 Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0 ...

  6. BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...

  7. Bzoj2763 [JLOI2011]飞行路线

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2651  Solved: 1004 Description Alice和Bob现在要乘飞机旅行,他们选 ...

  8. bzoj2763: [JLOI2011]飞行路线 分层图+dij+heap

    分析:d[i][j]代表从起点到点j,用了i次免费机会,那就可以最短路求解 #include <stdio.h> #include <iostream> #include &l ...

  9. [luogu4568][bzoj2763][JLOI2011]飞行路线

    题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为00到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定 ...

随机推荐

  1. Requirejs开篇

    前言 随着页面的内容丰富,以及网站体验更好.性能优化等,原有的通过script标签引入JavaScript脚本的方式已经不能很好地解决,此时新的一种JavaScript加载方式产生了--延时加载.执行 ...

  2. [译]Autoprefixer:用最可行的方式处理浏览器前缀的CSS后处理器

    Autoprefixer,通过Can I Use数据库来确定哪些浏览器前缀是需要的,然后解析CSS文件,将前缀添加到CSS规则里. 你所要做的就是添加你的资源构建工具(比如:Grunt),然后你就可以 ...

  3. DOM4j--write

    import java.io.File; import java.io.FileNotFoundException;import java.io.FileOutputStream;import jav ...

  4. c++ primer (5)2

    第三章 1.头文件不应包含using声明,因为头文件的内容会拷贝到所有引用它的文件中去. 2.初始化string对象的方式: string s1; //默认初始化,s1是一个空串 string s2( ...

  5. 第11条:谨慎地覆盖clone

    Clone提供一种语言之外的机制:无需调用构造器就可以创建对象. 它的通用约定非常弱: 创建和返回该对象的一个拷贝.这个拷贝的精确含义取决于该对象的类.一般含义是,对于任何对象x,表达式x.clone ...

  6. mysql时间与日期函数

    返回日期相关的 Now() || CURRENT_TIMESTAMP();返回当前时间 to_days(date) 返回日期date是西元0年至今多少天(不计算1582年以前) 转换为天数 date是 ...

  7. Vsftpd -- 验证方式

    vsftpd程序提供的FTP服务可选认证方式,分别为匿名访问.本地用户和虚拟用户: 匿名访问:任何人无需验证口令即可登入FTP服务端. 本地用户:使用FTP服务器中的用户.密码信息. 虚拟用户:创建独 ...

  8. SQL Server2008数据库导入导出兼容性处理

    使用场景:SQL Server 的高版本数据库恢复到低版本则可能会有兼容性问题,为了解决此类问题进行数据库脚本模式处理,数据库结构,及数据存储更换版本等. 1.  选择要导出的数据库,右键任务,生成脚 ...

  9. 三个PHP常用代码样例

    作为一个正常的程序员,会好几种语言是十分正常的,相信大部分程序员也都会编写几句PHP程序,如果是WEB程序员,PHP一定是必备的.尽管PHP经常被人诟病,被人贬低,被人当玩笑开,事实证明,PHP是全世 ...

  10. (转)互联网协议入门 ------ HTTP(1)

    作者:阮一峰 原文:http://www.ruanyifeng.com/blog/2012/06/internet_protocol_suite_part_ii.html 我们每天使用互联网,你是否想 ...