题目描述

Link

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

Alice 和 Bob 现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多 \(k\) 种航线上搭乘飞机。那么 Alice 和 Bob 这次出行最少花费多少?

分层图最短路的模板题。

发现自己好久不打,都快忘了怎么写了,临近 Csp,赶快复习一下。

分层图就是每一层都是一张原图,层与层之间在由边连接起来的图。

分层图具体表示的是使用 \(j\) 次免费通行的权限后到达 \(u\) 点的状态。

关于这道题,我们考虑怎么建图。

使用一张飞机票就代表我们走这条边的代价为 \(0\) ,我们可以有 \(i\) 这一层到 \(i+1\) 这一层的 \(u-v\) 连一条边权为零的边,

表示我们从 \(u\) 这个点到 \(v\) 这个点不需要花费代价。

为什么要往每一层都连边,是因为你坐飞机的顺序是不确定的。

图建出来大概长这样:

还要注意的点就是每一层的终点之间也要互相连边,因为你免费次数用几次可能会比都用完的方案要优。

我们最后最短路经过的边权为 \(0\) 的条数就是我们要用的免费次数。

关于 \(spfa\) ,他死了。别问我是怎么知道的,我就是在这里被卡的。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int N = 1e6+10;
struct node{int to,net,w;}e[2500010];
priority_queue< pair<int , int> , vector< pair<int,int> > , greater< pair<int,int> > >q;
int n,m,k,x,y,w,tot,s,t;
int dis[N],head[N];
bool vis[N];
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10 + ch -'0';ch = getchar();}
return s * w;
}
void add(int x , int y , int w)
{
e[++tot].to = y;
e[tot].w = w;
e[tot].net = head[x];
head[x] = tot;
}
void dfs(int x)//dij
{
memset(dis , 0x3f3f3f , sizeof(dis));
q.push(make_pair(0,x));
dis[x] = 0;
while(!q.empty())
{
int t = q.top().second; q.pop();
if(vis[t]) continue;
vis[t] = 1;
for(int i = head[t]; i; i = e[i].net)
{
int to = e[i].to;
if(dis[to] > dis[t] + e[i].w)
{
dis[to] = dis[t] + e[i].w;
q.push(make_pair(dis[to] , to));
}
}
}
}
int main()
{
n = read(); m = read(); k = read();
s = read(); t = read();
for(int i = 1; i <= m; i++)
{
x = read(); y = read(); w = read();
add(x,y,w); add(y,x,w);//原图上连边
for(int i = 1; i <= k; i++)
{
add(x + n * (i-1) , y + n * i , 0);//层与层之间的点连一条边权为0的边
add(y + n * (i-1) , x + n * i , 0);
add(x + n * i , y + n * i , w);//每一层按原图连边
add(y + n * i , x + n * i , w);
}
}
for(int i = 1; i <= k; i++) add(t + n * (i-1) , t + n * i , 0);//每一层终点之间互相连边
dfs(s);
printf("%d\n",dis[t + n * k]);
return 0;
}

P4568 [JLOI2011]飞行路线 / P2939 [USACO09FEB]Revamping Trails G的更多相关文章

  1. 洛谷 P4568 [JLOI2011]飞行路线 解题报告

    P4568 [JLOI2011]飞行路线 题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在\(n\)个城市设有业务,设这些城市分别标记为0到\(n−1\ ...

  2. 洛谷 P4568 [JLOI2011]飞行路线 题解

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

  3. [JLOI 2011]飞行路线&[USACO 09FEB]Revamping Trails

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

  4. [USACO09FEB] Revamping Trails 【分层图+Dijkstra】

    任意门:https://www.luogu.org/problemnew/show/P2939 Revamping Trails 题目描述 Farmer John dutifully checks o ...

  5. 洛谷 P4568 [JLOI2011]飞行路线

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

  6. 【luogu P4568 [JLOI2011]飞行路线】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4568 卡了一晚上,算是分层图最短路的模板.注意卡SPFA,所以我写了个SLF优化. 同时 AC400祭!~ ...

  7. P4568 [JLOI2011]飞行路线 分层图最短路

    思路:裸的分层图最短路 提交:1次 题解: 如思路 代码: #include<cstdio> #include<iostream> #include<cstring> ...

  8. luogu P4568 [JLOI2011]飞行路线

    传送门 看到免费次数\(k\)最多只有10,可以考虑构建\(k+1\)层的分层图,即每一层正常连边,上下两层对应点连边权为0的单向边,最后对所有层里面的\(di_t\)取\(\max\)救星了 #in ...

  9. P4568 [JLOI2011]飞行路线

    思路 套路题 建出k+1分层图,从上一层走到下一层代表坐了一次免费航线,跑最短路即可 注意可能有情况不需要耗完所有k次机会,所以应从每层的终点向下一层终点连一条边权为0的边 代码 #include & ...

随机推荐

  1. Tomcat9w.exe无法启动为started

    问题: startup.bat可以正常启动,http://localhost:8080/ 可以正常访问.但是Tomcat9w.exe无法启动为started,一直为Stopped. 解决方案: 如下图 ...

  2. CentOS如何设置IP连接网络

    1.登录系统,进入:cd /etc/sysconfig/network-scripts 目录下,如下图: 找到 ifcfg-ens33(文件) 第二步:使用vi编辑器打开ifcfg-ens33文件,使 ...

  3. 如何编写一个简单的Linux驱动(二)——设备操作集file_operations

    前期知识 如何编写一个简单的Linux驱动(一)--驱动的基本框架 前言 在上一篇文章中,我们学习了驱动的基本框架.这一章,我们会在上一章代码的基础上,继续对驱动的框架进行完善.要下载上一篇文章的全部 ...

  4. Java SPI详细的例子

    先翻一个来自于Baeldung的介绍: 为了更通俗易懂我就没有直译,如果有不严谨的地方请大神指教. JavaSPI的定义 Java SPI defines four main components S ...

  5. CSS 简介,学习 CSS 必看

    CSS 表示的是层叠样式表,学习 CSS 之前我们必须要掌握 HTML 和 XHTML 概述 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 ...

  6. 乔悟空-CTF-i春秋-Web-Not Found-🙋🏻‍♂️

    2020.09.08 又是匆匆忙忙的一天- 做题 题目 题目地址 做题 做题??做个屁,啥也不知道,干瞪眼

  7. [LeetCode]152. 乘积最大子序列(DP)

    题目 给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4] 输出: 6 解释: 子数组 [2,3] 有最大乘积 6. 示 ...

  8. vim配置汇总

    目录 配置行号 显示状态栏 设置提示换行线 配置行号 set number 效果 显示状态栏 set laststatus=2 设置提示换行线 set colorcolumn=81

  9. Elasticsearch安装、原理学习总结

    ElasticSearch ElasticSearch概念 Elasticsearch是Elastic Stack核心的分布式搜索和分析引擎. 什么是Elastic Stack Elastic Sta ...

  10. breakpad系列(2)——在Linux中使用breakpad

    本文来自breakpad源码目录中doc目录下的linux_starter_guide.md,建议直接去看原文. 如何将breakpad添加进你的Linux程序 本文档是在Linux上使用Breakp ...