题目链接: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 飞行路线【分层图最短路】的更多相关文章

  1. P4568 飞行路线 分层图最短路

    P4568 飞行路线 分层图最短路 分层图最短路 问题模型 求最短路时,可有\(k\)次更改边权(减为0) 思路 在普通求\(Dijkstra\)基础上,\(dis[x][j]\)多开一维\(j\)以 ...

  2. bzoj2763 [JLOI]飞行路线 分层图最短路

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

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

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

  4. BZOJ2763: [JLOI2011]飞行路线(分层图 最短路)

    题意 题目链接 Sol 分层图+最短路 建\(k+1\)层图,对于边\((u, v, w)\),首先在本层内连边权为\(w\)的无向边,再各向下一层对应的节点连边权为\(0\)的有向边 如果是取最大最 ...

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

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

  6. 【bzoj2763】[JLOI2011]飞行路线 分层图最短路

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

  7. bzoj 2763: [JLOI2011]飞行路线 -- 分层图最短路

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MB Description Alice和Bob现在要乘飞机旅行,他们选择了一家相 ...

  8. BZOJ2763[JLOI2011]飞行路线 [分层图最短路]

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2523  Solved: 946[Submit][Statu ...

  9. [JLOI2011]飞行路线 (分层图,最短路)

    题目链接 Solution 建立 \(k+1\) 层图跑 \(Dijkstra\) 就好了. Code #include<bits/stdc++.h> #define ll long lo ...

  10. [bzoj2763][JLOI2011]飞行路线——分层图最短路

    水题.不多说什么. #include <bits/stdc++.h> using namespace std; const int maxn = 10010; const int maxk ...

随机推荐

  1. 【HTTP】图解HTTPS

    我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取.所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议. HTTPS简介 HTTPS其实是有两部分组成:HTTP + SSL ...

  2. Django系列(一):前期准备

    1.web应用 Web应用程序是一种可以通过web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件.应用程序有两种模式C/S.B/S.C/S是客户端 ...

  3. Windows10+Jupyter notebook+添加核

    链接:https://blog.csdn.net/ZWX2445205419/article/details/80113472 1. 安装Anaconda   2. 创建虚拟环境   > con ...

  4. linux 查询cpu版本、核心、线程脚本

    #!/bin/bash #1.查看物理cpu个数 physical=`cat /proc/cpuinfo |grep 'physical id'|sort -u|wc -l` echo 物理cpu个数 ...

  5. 由Java正则表达式的灾难性回溯引发的高CPU异常:java.util.regex.Pattern$Loop.match

    问题与分析 某天领导report了一个问题:线上的CPU自从上一个版本迭代后就一直处于居高不下的状况,领导看着这段时间的曲线图判断是有两条线程在不停的死循环. 接到任务后去查看了AWS的CloudWa ...

  6. AT2306 Rearranging

    有一个显然的,就是不互质的数的相对位置是不会改变的,那么我们把它们放到一个连通块里面去,然后我交换就是交换两个里面最小的对吧.直接连起来然后跑\(TopSort\)就行了. #include<s ...

  7. 综述类文章(Peng 等)阅读笔记Cross-media analysis and reasoning: advances and directions

    综述类文章 Cross-media analysis and reasoning: advances and directions Yu-xin PENG et al. Front Inform Te ...

  8. lucene正向索引(续)——域(Field)的元数据信息在.fnm里,在倒排表里,利用跳跃表,有利于大大提高搜索速度。

    4.1.2. 域(Field)的元数据信息(.fnm) 一个段(Segment)包含多个域,每个域都有一些元数据信息,保存在.fnm文件中,.fnm文件的格式如下: FNMVersion 是fnm文件 ...

  9. html 与 xml 的区别与联系

    [引言] 前一阵子刚刚学习了html(HyperText Markup Language),最近又接触了xml(Extensible Markup Language),它们之间有什么联系和区别呢?现在 ...

  10. centos7.2下查看的java版本号

    1,centos7.2下查看的java版本号 java -version