分层图【p4568】 [JLOI2011]飞行路线
Description
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在nn个城市设有业务,设这些城市分别标记为\(0\)到\(n−1\),一共有\(m\)种航线,每种航线连接两个城市,并且航线有一定的价格。
Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多\(k\)种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
Input
数据的第一行有三个整数,\(n,m,k\),分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,\(s,t\),分别表示他们出行的起点城市编号和终点城市编号。
接下来有\(m\)行,每行三个整数,\(a,b,c\),表示存在一种航线,能从城市\(a\)到达城市\(b\),或从城市\(b\)到达城市\(a\),价格为\(c\)。
Output
只有一行,包含一个整数,为最少花费
分析
明显,此题为最短路问题,但是考虑到可以免费搭乘(即直接通过一条边无需费用.)
这种问题有一个较官方的名字 分层图最短路问题
分层图最短路是指在可以进行分层图的图上解决最短路问题.
是不是听起来就很nb?
具体分层图是啥,我也不知道
一般模型:
在图上,有\(k\)次机会可以直接通过一条边,问起点与终点之间的最短路径.
很明显,这道题是一个裸的分层图最短路问题 (貌似这类问题都挺裸的 emm
解法
我们设
\(dis[i][j]\)代表到达\(i\)用了\(j\)次免费机会的最小花费.
\(vis[i][j]\)代表到达\(i\)用了\(j\)次免费机会的情况是否出现过.
对于某条路径我们可以选择使用机会,也可以选择不使用机会.
讨论这两种情况即可
#include<cstdio>
#include<queue>
#include<cstring>
#define R register
#define N 20008
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(s>'9' or s<'0'){if(s=='-')f=-1;s=getchar();}
while(s>='0' and s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int head[N],tot,n,m,s,t,k;
int dis[N][15],ans=2147483647;
bool vis[N][15];
struct cod{int u,v,w;}edge[N*6+8];
inline void add(int x,int y,int z)
{
edge[++tot].u=head[x];
edge[tot].v=y;
edge[tot].w=z;
head[x]=tot;
}
struct coc{
int u,d,used;
bool operator <(const coc&a) const
{
return d>a.d;
}
};
inline void dijkstra()
{
memset(dis,127,sizeof dis);
dis[s][0]=0;
priority_queue<coc>q;
q.push((coc){s,0,0});
while(!q.empty())
{
int u=q.top().u,now=q.top().used;
q.pop();
if(vis[u][now])continue;
vis[u][now]=true;
for(R int i=head[u];i;i=edge[i].u)
{
if(now<k and !vis[edge[i].v][now+1] and dis[edge[i].v][now+1]>dis[u][now])//当前路径,使用一次免费机会.注意判断 now<k
{
dis[edge[i].v][now+1]=dis[u][now];
q.push((coc){edge[i].v,dis[edge[i].v][now+1],now+1});
}
if(!vis[edge[i].v][now] and dis[edge[i].v][now]>dis[u][now]+edge[i].w)//当前路径,不使用免费机会
{
dis[edge[i].v][now]=dis[u][now]+edge[i].w;
q.push((coc){edge[i].v,dis[edge[i].v][now],now});
}
}
}
}
int main()
{
in(n),in(m),in(k);
in(s),in(t);
s++;t++;//这里个人习惯不同.我选择记录编号为1~n
for(R int i=1,x,y,z;i<=m;i++)
{
in(x),in(y),in(z);
x++;y++;
add(x,y,z);
add(y,x,z);
}
dijkstra();//直接跑dijkstra
for(R int i=0;i<=k;i++)
ans=min(ans,dis[t][i]);//到达t我们需要对使用免费机会的情况枚举.取min
printf("%d",ans);
}
分层图【p4568】 [JLOI2011]飞行路线的更多相关文章
- 洛谷 P4568 [JLOI2011]飞行路线 解题报告
P4568 [JLOI2011]飞行路线 题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在\(n\)个城市设有业务,设这些城市分别标记为0到\(n−1\ ...
- 洛谷 P4568 [JLOI2011]飞行路线 题解
P4568 [JLOI2011]飞行路线 题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在\(n\)个城市设有业务,设这些城市分别标记为\(0\)到\( ...
- P4568 [JLOI2011]飞行路线(分层图)
机房dalao推荐写的...(标签分层图) 经过前几题的分层图的洗礼,我深刻地体会到了分层图的优点和好处(主要是不想打dp....) 先说题吧.... 很明确,模型是最短路,但是,怎么跑k个,是个问题 ...
- P4568 [JLOI2011]飞行路线 分层图
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在nn个城市设有业务,设这些城市分别标记为00到n-1n−1,一共有mm种航线,每种航线连接两个城市,并且 ...
- P4568 [JLOI2011]飞行路线 分层图最短路
思路:裸的分层图最短路 提交:1次 题解: 如思路 代码: #include<cstdio> #include<iostream> #include<cstring> ...
- 【luogu P4568 [JLOI2011]飞行路线】 题解
题目链接:https://www.luogu.org/problemnew/show/P4568 卡了一晚上,算是分层图最短路的模板.注意卡SPFA,所以我写了个SLF优化. 同时 AC400祭!~ ...
- luogu P4568 [JLOI2011]飞行路线
传送门 看到免费次数\(k\)最多只有10,可以考虑构建\(k+1\)层的分层图,即每一层正常连边,上下两层对应点连边权为0的单向边,最后对所有层里面的\(di_t\)取\(\max\)救星了 #in ...
- P4568 [JLOI2011]飞行路线
思路 套路题 建出k+1分层图,从上一层走到下一层代表坐了一次免费航线,跑最短路即可 注意可能有情况不需要耗完所有k次机会,所以应从每层的终点向下一层终点连一条边权为0的边 代码 #include & ...
- [洛谷P4568][JLOI2011]飞行路线
题目大意:最短路,可以有$k$条边无费用 题解:分层图最短路,建成$k$层,层与层之间的边费用为$0$ 卡点:空间计算出错,建边写错 C++ Code: #include <cstdio> ...
- P4568 [JLOI2011]飞行路线 / P2939 [USACO09FEB]Revamping Trails G
题目描述 Link Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在 \(n\) 个城市设有业务,设这些城市分别标记为 \(0\) 到 \(n-1\),一共 ...
随机推荐
- 去掉referer信息
<iframe src="auto-refresh.html" width=500 height=500 rel="noreferrer">< ...
- Windows Phone 图片扩展类
using System.IO; using System.Text; using System.Net; using System.Threading.Tasks; using System.Win ...
- 二叉树 【转】http://blog.csdn.net/sjf0115/article/details/8645991
//二叉树 #include<iostream> #include<stack> #include<queue> using namespace std; //二叉 ...
- Redis常用知识
1.redis是什么 redis是一种支持Key-Value等多种数据结构的存储系统.可用于缓存.事件发布或订阅.高速队列等场景.该数据库使用ANSI C语言编写,支持网络,提供字符串.哈希.列表.队 ...
- python-configparser模块,xml.etree模块
操作键值对文件 #文件db格式为 [section] a = 1 b = 2 [section1] d = 3 c = 4 import configparser #获取所有节点 config = c ...
- Lua3
Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础.如数组.记录.线性表.队列和集合等,在Lua中都可以通过table来表示. 1.数组 使用整数来索引table即可在Lua中实 ...
- .net发展-关注
文章:用.net core 写后端—— c++外的另一种选择? 文章:
- poj1936 假期计划第一水
All in All Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 29651 Accepted: 12312 Desc ...
- Servlet中文件上传
利用getReader()和getInputstream()上传 package control; import javax.servlet.ServletException; import java ...
- JavaScript中继承机制的模仿实现
首先,我们用一个经典例子来简单阐述一下ECMAScript中的继承机制. 在几何学上,实质上几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边).圆是椭圆的一种,它只有一个焦点.三角形. ...