分层图求最短路
2026/9/1 4:59:34 网站建设 项目流程

P4568 [JLOI2011] 飞行路线

题目描述

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

Alice and Bob now need to travel from one city to another along the routes, with possible transfers in between. The airline is also offering a special deal for this trip: they can fly for free on up tok kkroutes. So what is the minimum cost for Alice and Bob’s trip?

输入格式

第一行三个整数n , m , k n,m,kn,m,k,分别表示城市数,航线数和免费乘坐次数。

接下来一行两个整数s , t s,ts,t,分别表示他们出行的起点城市编号和终点城市编号。

接下来m mm行,每行三个整数a , b , c a,b,ca,b,c,表示存在一种航线,能从城市a aa到达城市b bb,或从城市b bb到达城市a aa,价格为c cc

输出格式

输出一行一个整数,为最少花费。

输入输出样例 #1

输入 #1

5 6 1 0 4 0 1 5 1 2 5 2 3 5 3 4 5 2 3 3 0 2 100

输出 #1

8

说明/提示

数据规模与约定

对于30 % 30\%30%的数据,2 ≤ n ≤ 50 2 \le n \le 502n501 ≤ m ≤ 300 1 \le m \le 3001m300k = 0 k=0k=0

对于50 % 50\%50%的数据,2 ≤ n ≤ 600 2 \le n \le 6002n6001 ≤ m ≤ 6 × 10 3 1 \le m \le 6\times10^31m6×1030 ≤ k ≤ 1 0 \le k \le 10k1

对于100 % 100\%100%的数据,2 ≤ n ≤ 10 4 2 \le n \le 10^42n1041 ≤ m ≤ 5 × 10 4 1 \le m \le 5\times 10^41m5×1040 ≤ k ≤ 10 0 \le k \le 100k100 ≤ s , t , a , b < n 0\le s,t,a,b < n0s,t,a,b<na ≠ b a\ne ba=b0 ≤ c ≤ 10 3 0\le c\le 10^30c103

另外存在一组 hack 数据。

题解

建图模型:

我们将每个城市u uu拆分成k + 1 k+1k+1个节点,记为( u , j ) (u, j)(u,j),其中0 ≤ j ≤ k 0 \le j \le k0jk
( u , j ) (u, j)(u,j)表示当前位于城市u uu,且已经使用了j jj次免费机会的状态。

边的构建:

对于原图中的一条边( a , b , c ) (a, b, c)(a,b,c)

运行 Dijkstra:

( s , 0 ) (s, 0)(s,0)为源点跑 Dijkstra 算法。
最终答案为min ⁡ { d i s t [ t ] [ j ] ∣ 0 ≤ j ≤ k } \min\{dist[t][j] \mid 0 \le j \le k\}min{dist[t][j]0jk},即到达终点t tt时使用了任意不超过k kk次免费机会的最小花费。

复杂度分析:

代码

#include<iostream>#include<cstring>#include<algorithm>#include<vector>#include<queue>usingnamespacestd;typedeflonglongLL;typedefpair<LL,int>PLI;constLL INF=1e18;constintN=1e4+10,K=11;structedge{intne;LL w;};intn,m,k;ints,t;vector<vector<edge>>adj(N*K);LL dist[N*K];boolst[N*K];intmain(){ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m>>k>>s>>t;intlayers=k+1;for(inti=0;i<m;i++){inta,b,c;cin>>a>>b>>c;for(intj=0;j<=k;j++){// 付费边adj[a*layers+j].push_back({b*layers+j,c});adj[b*layers+j].push_back({a*layers+j,c});// 免费边if(j<k){adj[a*layers+j].push_back({b*layers+j+1,0});adj[b*layers+j].push_back({a*layers+j+1,0});}}}// Dijkstrafor(inti=0;i<N*K;i++)dist[i]=INF;priority_queue<PLI,vector<PLI>,greater<>>q;dist[s*layers+0]=0;q.push({0,s*layers+0});while(q.size()){auto[d,u]=q.top();q.pop();if(st[u])continue;st[u]=true;for(auto&e:adj[u]){LL nd=d+e.w;if(nd<dist[e.ne]){dist[e.ne]=nd;q.push({nd,e.ne});}}}LL res=INF;for(intj=0;j<=k;j++)res=min(res,dist[t*layers+j]);cout<<res<<endl;return0;}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询