P4568 飞行路线【分层图最短路】
题目链接:https://www.luogu.org/problem/P4568
题目大意:给定n个点,m条无向边,k次机会经过边时代价为 0 。给出起点和终点,求其最短路径。
解题思路:
两种方法,一是用拆点分层,直接跑最短路。二是dis[][]开二维数组,表示已经用了 j 次免费机会时在 i 点的最短路径。
第一种方法数组需要多开大很多倍(因为拆点),当层数以及点比较多的时候,边也就非常多,代码跑起来很慢,在这里若不用优先队列dijsktra优化会超时。
第二种方法似乎更加好,不需要将一维数组开大很多倍,只需要用二维数组记录状态,然后更新即可。跑的边也会比较的少。代码更快。
对于第一种方法。图如下:

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int MAXN = 1e6 + ;//建了多层 点成倍增加
const int MAXM = 5e6 + ;
const int inf = 0x3f3f3f3f;
using namespace std; int n, m, k, st, ed;
int head[MAXN], cnt;
int vis[MAXN];
ll dis[MAXN]; //距离开ll 稳 struct Edge
{
int to, next;
ll w;
}edge[MAXM]; struct Node
{
int pot;
ll dis;
bool operator < (const Node &a)const
{
return dis > a.dis;
}
}node; void add(int a, int b, ll c)
{
cnt ++;
edge[cnt].to = b;
edge[cnt].w = c;
edge[cnt].next = head[a];
head[a] = cnt;
} void dij()
{
mem(dis, inf), mem(vis, );
priority_queue<Node> Q; //记得是优先队列
while(!Q.empty()) Q.pop();
dis[st] = ;
node.pot = st, node.dis = ;
Q.push(node);
while(!Q.empty())
{
Node a = Q.top();//top()
Q.pop();
if(vis[a.pot])
continue;
vis[a.pot] = ;
for(int i = head[a.pot]; i != -; i = edge[i].next)
{
int to = edge[i].to;
if(vis[to]) //若该点以及确定了最短距离 则不需要再去比较了
continue;
if(dis[to] > dis[a.pot] + edge[i].w)
{
dis[to] = dis[a.pot] + edge[i].w;
node.pot = to, node.dis = dis[to];
Q.push(node);
}
}
}
} int main()
{
cnt = , mem(head, -);
scanf("%d%d%d", &n, &m, &k);
scanf("%d%d", &st, &ed);
for(int i = ; i <= m; i ++)
{
int a, b;
ll c;
scanf("%d%d%lld", &a, &b, &c);
add(a, b, c);
add(b, a, c);
for(int j = ; j <= k; j ++)
{
add(a + (j - ) * n, b + j * n, ); //上一层往下一层建边权为 0 的边
add(b + (j - ) * n, a + j * n, );
add(a + j * n, b + j * n, c); //每一层本身的边也要建
add(b + j * n, a + j * n, c);
}
}
dij();
ll ans = inf;
for(int i = ; i <= k; i ++) //选择到终点距离最短的那一层答案
ans = min(ans, dis[ed + i * n]);
printf("%lld\n", ans);
return ;
}
建图时分层
#include<stdio.h>
#include<string.h>
#include<queue>
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int MAXN = 1e4 + ;
const int MAXM = 5e4 + ;
const int inf = 0x3f3f3f3f;
using namespace std; int n, m, k, st, ed;
int head[MAXN], cnt, vis[MAXN][];
ll dis[MAXN][]; struct Edge
{
int to, next;
ll w;
}edge[ * MAXM]; struct Node
{
int pot, num; //点 以及 用了的机会次数
ll dis;
bool operator < (const Node &a)const
{
return dis > a.dis;
}
}node; void add(int a, int b, ll c)
{
cnt ++;
edge[cnt].w = c;
edge[cnt].to = b;
edge[cnt].next = head[a];
head[a] = cnt;
} void dij()
{
mem(dis, inf), mem(vis, );
node.pot = st, node.dis = , node.num = ;
dis[st][] = ;
priority_queue<Node> Q;
Q.push(node);
while(!Q.empty())
{
Node a = Q.top();
Q.pop();
if(vis[a.pot][a.num])
continue;
vis[a.pot][a.num] = ;
for(int i = head[a.pot]; i != -; i = edge[i].next)
{
int to = edge[i].to;
if(dis[to][a.num] > dis[a.pot][a.num] + edge[i].w) //不使用免费机会
{
dis[to][a.num] = dis[a.pot][a.num] + edge[i].w;
node.pot = to, node.dis = dis[to][a.num], node.num = a.num;
Q.push(node);
}
if(a.num == k) //如果已经把免费机会使用完了
continue;
if(dis[to][a.num + ] > dis[a.pot][a.num])
{
dis[to][a.num + ] = dis[a.pot][a.num];
node.pot = to, node.dis = dis[to][a.num + ], node.num = a.num + ;
Q.push(node);
}
}
}
} int main()
{
mem(head, -), cnt = ;
scanf("%d%d%d", &n, &m, &k);
scanf("%d%d", &st, &ed);
for(int i = ; i <= m; i ++)
{
int a, b;
ll c;
scanf("%d%d%lld", &a, &b, &c);
add(a, b, c);
add(b, a, c);
}
dij();
ll ans = inf;
for(int i = ; i <= k; i ++)
ans = min(ans, dis[ed][i]);
printf("%lld\n", ans);
return ;
}
二维数组
P4568 飞行路线【分层图最短路】的更多相关文章
- P4568 飞行路线 分层图最短路
P4568 飞行路线 分层图最短路 分层图最短路 问题模型 求最短路时,可有\(k\)次更改边权(减为0) 思路 在普通求\(Dijkstra\)基础上,\(dis[x][j]\)多开一维\(j\)以 ...
- bzoj2763 [JLOI]飞行路线 分层图最短路
问题描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的 ...
- P4568 [JLOI2011]飞行路线 分层图最短路
思路:裸的分层图最短路 提交:1次 题解: 如思路 代码: #include<cstdio> #include<iostream> #include<cstring> ...
- BZOJ2763: [JLOI2011]飞行路线(分层图 最短路)
题意 题目链接 Sol 分层图+最短路 建\(k+1\)层图,对于边\((u, v, w)\),首先在本层内连边权为\(w\)的无向边,再各向下一层对应的节点连边权为\(0\)的有向边 如果是取最大最 ...
- [JLOI2011]飞行路线 分层图最短路
题目描述: Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在nn个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一 ...
- 【bzoj2763】[JLOI2011]飞行路线 分层图最短路
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的 ...
- bzoj 2763: [JLOI2011]飞行路线 -- 分层图最短路
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MB Description Alice和Bob现在要乘飞机旅行,他们选择了一家相 ...
- BZOJ2763[JLOI2011]飞行路线 [分层图最短路]
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2523 Solved: 946[Submit][Statu ...
- [JLOI2011]飞行路线 (分层图,最短路)
题目链接 Solution 建立 \(k+1\) 层图跑 \(Dijkstra\) 就好了. Code #include<bits/stdc++.h> #define ll long lo ...
- [bzoj2763][JLOI2011]飞行路线——分层图最短路
水题.不多说什么. #include <bits/stdc++.h> using namespace std; const int maxn = 10010; const int maxk ...
随机推荐
- Linux操作系统常用命令合集——第六篇-压缩和归档操作(16个命令)
1.gzip [命令作用] 压缩和解压缩文件 gzip/guzip/zcat zcat:不显式展开的前提下查看文本文件内容 zdiff/zgrep/zless/zmore [命令语法] gzip ...
- loj 2011
对于第 $i$ 天的询问前 $i - c - 1$ 天都会影响答案主席树维护 #include <iostream> #include <cstdio> #include &l ...
- 数据结构实验之查找三:树的种类统计(SDUT 3375)
C: #include <stdio.h> #include <stdlib.h> #include <string.h> struct node { char d ...
- Ubuntu上配置vtk开发环境——基于visual studio code 与 gcc
环境说明 vtk版本7.1.1 visual studio 1.16.1 Ubuntu 16.04 + 自带的gcc 编译过程与windows下类似还好,运行自己的代码开始面对cmake与make的各 ...
- ros topic 命令
#查看topic频率rostopic hz /xxx_imu_driver/imu #查看topic信息rostopic info /xxx_imu_driver/imu #查看topic数据rost ...
- vue.js 中this.$router.push()的使用
在vue项目中,跳转可以用router-link直接跳到某个页面 因为有时候会需要做一些判断等情况,所以要用到 this.$router.push() 因为外链跳转根本就不在router的设计考虑范围 ...
- java集合类型源码解析之PriorityQueue
本来第二篇想解析一下LinkedList,不过扫了一下源码后,觉得LinkedList的实现比较简单,没有什么意思,于是移步PriorityQueue. PriorityQueue通过数组实现了一个堆 ...
- LC 989. Add to Array-Form of Integer
For a non-negative integer X, the array-form of X is an array of its digits in left to right order. ...
- SQL-W3School-函数:SQL COUNT() 函数
ylbtech-SQL-W3School-函数:SQL COUNT() 函数 1.返回顶部 1. COUNT() 函数返回匹配指定条件的行数. SQL COUNT() 语法 SQL COUNT(col ...
- [Java复习] 多线程 并发 JUC 补充
线程安全问题? 当多个线程共享同一个全局变量,做写的操作时,可能会受到其他线程的干扰.读不会发生线程安全问题. -- Java内存模型. 非静态同步方法使用什么锁? this锁 静态同步方法使用什么 ...