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个堆……
语言表述有点渣,具体还是看程序吧
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的更多相关文章
- BZOJ2763[JLOI2011]飞行路线 [分层图最短路]
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2523 Solved: 946[Submit][Statu ...
- 【BZOJ2763】飞行路线(最短路)
[BZOJ2763]飞行路线(最短路) 题面 BZOJ Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标 ...
- BZOJ2763 JLOI2011 飞行路线 【最短路+DP】
BZOJ2763 JLOI2011 飞行路线 Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n ...
- 【bzoj2763】[JLOI2011]飞行路线 (分层图最短路)(优先队列dij)
[bzoj2763][JLOI2011]飞行路线 2014年3月25日1,7260 Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城 ...
- 分层图最短路【bzoj2763】: [JLOI2011]飞行路线
bzoj2763: [JLOI2011]飞行路线 Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0 ...
- BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...
- Bzoj2763 [JLOI2011]飞行路线
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2651 Solved: 1004 Description Alice和Bob现在要乘飞机旅行,他们选 ...
- bzoj2763: [JLOI2011]飞行路线 分层图+dij+heap
分析:d[i][j]代表从起点到点j,用了i次免费机会,那就可以最短路求解 #include <stdio.h> #include <iostream> #include &l ...
- [luogu4568][bzoj2763][JLOI2011]飞行路线
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为00到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定 ...
随机推荐
- [GeekBand] C++学习笔记(2)——BigThree、OOP
本篇笔记主要分为三个部分,第一部分是以String类为例的基于对象的编程,重点在于构造与析构.拷贝构造函数.拷贝赋值函数三个重要函数.这一部分与笔记(1)中的内容结合起来就是基于对象编程的主要内容.第 ...
- Hibernate3.3 小记
//----------------事务(修改.删除.保存) Session s=getSession(); Transaction t=s.beginTransaction(); getSessio ...
- dd命令测试linux磁盘读写速度
1.先熟悉两个特殊的设备: (1)/dev/null:回收站.无底洞. (2)/dev/zero:产生字符. 2.测试磁盘写能力 time dd if=/dev/zero of=/t ...
- 轻松解决fedora21装完NVIDIA显卡驱动后无法进入gnome问题
本来打算昨天写的,最近感冒了,打点滴,耽搁了! 我用的是联想14寸笔记本,装好了fedora21后,想装个NVIDIA显卡驱动试试,结果和很多人一样无法进入gnome界面,搞了三四个小时终于搞定.下面 ...
- 小shell函数
whoport() { port=$1 echo "------ who occupied port: $port ----------" info=$(sudo lsof ...
- ECMAScript布尔操作符
在ECMAScript中提供了Boolean()转换函数以及三个布尔操作符,这三个布尔操作符分别为逻辑非.逻辑与.逻辑或,这三个操作符通常用作于某些值的求反,比较模式等.学好这一点知识也非常的重要,奠 ...
- c#通过反射获取类上的自定义特性
c#通过反射获取类上的自定义特性 本文转载:http://www.cnblogs.com/jeffwongishandsome/archive/2009/11/18/1602825.html 下面这个 ...
- cocos2d-x学习笔记------动画人物跑起来吧!
学习总结: 1.sprintf用来格式化字符串 2.CCSpriteFrame:: frameWithTexture通过图片名创建的时候需要的参数Texture2D创建使用CCTextureCache ...
- C#动态生成图书信息XML文件
通过C#动态生成图书信息XML文件,下面有个不错的示例,需要的朋友可以参考下 通过C#动态生成图书信息XML文件(Books.xml),文件如下: 复制代码代码如下: <?xml version ...
- Django基本介绍
Django板块分类: 1.urls.py 网址的入口(关联到views.py中的一个函数) 2.views.py 处理用户发起的请求,从urls.py中对应过来,通过渲染templates中的网页 ...