【洛谷P4568】飞行路线【分层图最短路】

2024-01-30 10:08

本文主要是介绍【洛谷P4568】飞行路线【分层图最短路】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P4568
一张无向图,每条边有权值,可以选择不超过 k k k条路使这条路的权值变为0。求从 S S S T T T的最短路。


思路:

做这道题的原因:随机跳题 P a r t 3 Part3 Part3跳到了分层图最短路的题目 q w q qwq qwq
这道题算是分成图最短路的模板吧。
由于题目中说有 k k k条道路可以免费,所以直接跑最短路暴力判断显然是不行的。
分层图最短路就可以有效解决这种带有 「阶段性」的最短路。
我们把整个图分成 k + 1 k+1 k+1层( 0 ∼ k 0\sim k 0k),第 k k k层表示已经将 k k k条道路免费的图,也就是说,每一层的道路和普通的最短路没有什么区别,只是多了一些从第 i i i层到第 i + 1 i+1 i+1层的道路。这些道路的权值为0,这样就有效解决了免费的情况,因为如果最短路跑到了第 i i i层说明使 i i i条道路免费了。
最终把每一层的终点连向一个超级汇点,权值为0,最短路就是第0层源点到超级汇点的最短路。
这道题还把我 s p f a spfa spfa卡了,敲了个 d i j dij dij才过。


代码:

#include <queue>
#include <cstdio>
#include <cstring>
#define mp make_pair
using namespace std;const int N=300010,M=3000100;
int n,m,k,S,T,T_,tot,head[N],dis[N];
bool vis[N];struct edge
{int next,to,dis;
}e[M];void add(int from,int to,int dis)
{e[++tot].to=to;e[tot].dis=dis;e[tot].next=head[from];head[from]=tot;
}void dij()
{memset(dis,0x3f3f3f3f,sizeof(dis));priority_queue<pair<int,int> > q;q.push(mp(0,S));dis[S]=0;while (q.size()){int u=q.top().second,v;q.pop();if (vis[u]) continue;vis[u]=1;for (int i=head[u];~i;i=e[i].next){v=e[i].to;if (dis[v]>dis[u]+e[i].dis){dis[v]=dis[u]+e[i].dis;q.push(mp(-dis[v],v));}}}
}int main()
{memset(head,-1,sizeof(head));scanf("%d%d%d%d%d",&n,&m,&k,&S,&T_);T=N-1; S++; T_++; k++;for (int i=1,x,y,z;i<=m;i++){scanf("%d%d%d",&x,&y,&z);x++; y++;for (int i=1;i<=k;i++){add(i*n-n+x,i*n-n+y,z);add(i*n-n+y,i*n-n+x,z);if (i<k){add(i*n-n+x,i*n+y,0);add(i*n-n+y,i*n+x,0);}}}for (int i=1;i<=k;i++)add(i*n-n+T_,T,0);dij();printf("%d\n",dis[T]);return 0;
}

这篇关于【洛谷P4568】飞行路线【分层图最短路】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/659904

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

poj 3159 (spfa差分约束最短路) poj 1201

poj 3159: 题意: 每次给出b比a多不多于c个糖果,求n最多比1多多少个糖果。 解析: 差分约束。 这个博客讲差分约束讲的比较好: http://www.cnblogs.com/void/archive/2011/08/26/2153928.html 套个spfa。 代码: #include <iostream>#include <cstdio>#i

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

poj 3255 次短路(第k短路) A* + spfa 或 dijkstra

题意: 给一张无向图,求从1到n的次短路。 解析: A* + spfa 或者 dijkstra。 详解见上一题:http://blog.csdn.net/u013508213/article/details/46400189 本题,spfa中,stack超时,queue的效率最高,priority_queue次之。 代码: #include <iostream>#i

poj 2449 第k短路 A* + spfa

poj 2449: 题意: 给一张有向图,求第k短路。 解析: A* + spfa。 一下转自:http://blog.csdn.net/mbxc816/article/details/7197228 “描述一下怎样用启发式搜索来解决K短路。 首先我们知道A*的基础公式:f(x)=g(x)+h(x);对h(x)进行设计,根据定义h(x)为当前的x点到目标点t所需要的实际距

poj 3259 最短路负环

John的农场里N块地,M条路连接两块地,W个虫洞,虫洞是一条单向路,会在你离开之前把你传送到目的地,就是当你过去的时候时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。简化下,就是看图中有没有负权环。有的话就是可以,没有的话就是不可以了。 import java.io.BufferedReader;import java.io.InputStream;

POJ1724最短路

n个点,拥有总的价值money m条边(u,v,len ,cost),长度len,代价cost 求不超过money的代价条件下最短路。 public class Main {public static void main(String[] args) {new Task().solve();}}class Task {InputReader in = new InputReader