P4568 [JLOI2011] 飞行路线
题目描述
Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在 n 个城市设有业务,设这些城市分别标记为 0 到 n−1,一共有 m 种航线,每种航线连接两个城市,并且航线有一定的价格。
Alice 和 Bob 现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多 k 种航线上搭乘飞机。那么 Alice 和 Bob 这次出行最少花费多少?
输入格式
第一行三个整数 n,m,k,分别表示城市数,航线数和免费乘坐次数。
接下来一行两个整数 s,t,分别表示他们出行的起点城市编号和终点城市编号。
接下来 mm 行,每行三个整数 a,b,c,表示存在一种航线,能从城市 a 到达城市 b,或从城市 b 到达城市 a,价格为 c。
输出格式
输出一行一个整数,为最少花费。
输入输出样例
5 6 1 0 4 0 1 5 1 2 5 2 3 5 3 4 5 2 3 3 0 2 100
8
说明/提示
数据规模与约定
对于 30% 的数据,2≤n≤50,1≤m≤300,k=0。
对于 50% 的数据,2≤n≤600,1≤m≤6×103,0≤k≤1。
对于 100% 的数据,2≤n≤104,1≤m≤5×104,0≤k≤10,0≤s,t,a,b≤n,a≠b,0≤c≤103。
另外存在一组 hack 数据。
浅看一下题,发现那个k是真的很烦。
没有k的话不就是标准的最短路吗?
带着略有无奈的心情继续往下翻……!!!什么!!!k∈[0,10]!!!
这是一个关键啊,没想到k竟然这么小。
要不,分十种情况讨论?算了吧,代码这不写死人吗。
继续思考…………!免费的路线,不就是边权为0吗?
k挺小的,那么就可以考虑建分层图了。
把图分为两层,各层内部正常连边,各层之间对应点从上到下连权值为0的边。每向下跑一层,就相当于免费搭一次飞机。跑一遍从s到 t+n∗k的最短路即可。
下图是样例数据间的分层图:
于是乎,这道题就被愉快地解决了。
等等:既然要建分层图,数组一定要开大点啊!!!
const int N=1e7+5; 完全没问题。
Code:
#include<bits/stdc++.h> using namespace std; const int N=1e7+5; int n,m,k,s,t,tot; int d[N],fi[N],ne[N*2],to[N*2],w[N*2]; bool vis[N]; priority_queue<pair<int,int> > q; void add(int x,int y,int z) { ne[++tot]=fi[x]; fi[x]=tot; to[tot]=y; w[tot]=z; } void dfs() { memset(d,0x7f,sizeof(d)); d[s]=0; q.push(make_pair(0,s)); while(!q.empty()) { int x=q.top().second; q.pop(); if(vis[x]) continue; vis[x]=1; for(int i=fi[x];i;i=ne[i]) { int v=to[i]; if(d[v]>d[x]+w[i]) { d[v]=d[x]+w[i]; q.push(make_pair(-d[v],v)); } } } } int main() { cin>>n>>m>>k>>s>>t; for(int i=1;i<=m;i++) { int x,y,z; cin>>x>>y>>z; add(x,y,z),add(y,x,z); for(int j=1;j<=k;j++) { add(x+(j-1)*n,y+j*n,0); add(y+(j-1)*n,x+j*n,0); add(x+j*n,y+j*n,z); add(y+j*n,x+j*n,z); } } for(int i=1;i<=k;i++) add(t+(i-1)*n,t+i*n,0); dfs(); cout<<d[t+k*n]<<'\n'; }
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现