「JLOI2011」「LuoguP4568」飞行路线(分层图最短路

题目描述

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

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

输入输出格式

输入格式:

数据的第一行有三个整数,n,m,kn,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,ts,t,分别表示他们出行的起点城市编号和终点城市编号。
接下来有m行,每行三个整数,a,b,ca,b,c,表示存在一种航线,能从城市aa到达城市bb,或从城市bb到达城市aa,价格为cc。

输出格式:

只有一行,包含一个整数,为最少花费。

输入输出样例

输入样例#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%的数据,2 \le n \le 50,1 \le m \le 300,k=02≤n≤50,1≤m≤300,k=0;
对于50%的数据,2 \le n \le 600,1 \le m \le 6000,0 \le k \le 12≤n≤600,1≤m≤6000,0≤k≤1;
对于100%的数据,2 \le n \le 10000,1 \le m \le 50000,0 \le k \le 102≤n≤10000,1≤m≤50000,0≤k≤10,0 \le s,t<n,0 \le a,b<n,a\neq b,0 \le c \le 10000≤s,t<n,0≤a,b<n,a≠b,0≤c≤1000

题解

建分层图就好了qwq

建k+1层,其中第i层表示用掉了(i-1)次免费票。

每条边在对应层建边,也在相邻一层的方向建免费边。

感觉这个图建的非常有网络流的感觉呢。

 1  qwerta
 2 P4568 [JLOI2011]飞行路线 Accepted
 3 100
 4 代码 C++,1.24KB
 5 提交时间 2018-11-02 19:35:30
 6 耗时/内存 617ms, 26264KB
 7 #include<iostream>
 8 #include<cstring>
 9 #include<cstdio>
10 #include<queue>
11 using namespace std;
12 const int MAXN=10000+3,MAXM=50000+3;
13 struct emm{
14     int e,f,l;
15 }a[11*4*MAXM];
16 int h[11*MAXN];
17 int tot=0;
18 int n,k;
19 void con(int x,int y,int l)
20 {
21     //cout<<"con "<<x<<" "<<y<<" "<<l<<endl;
22     a[++tot].f=h[x];
23     h[x]=tot;
24     a[tot].e=y;
25     a[tot].l=l;
26     return;
27 }
28 void add(int x,int y,int l)
29 {
30     for(int c=0;c<=k;++c)
31     {
32         int u=x+c*n,v=y+c*n;
33         con(u,v,l);
34         con(v,u,l);
35     }
36     for(int c=0;c<k;++c)
37     {
38         int u=x+c*n,v=y+(c+1)*n;
39         con(u,v,0);
40         u=x+(c+1)*n,v=y+c*n;
41         con(v,u,0);
42     }
43 }
44 struct ahh{
45     int nod,v;
46 };
47 struct cmp{
48     bool operator()(ahh qaq,ahh qwq){
49         return qaq.v>qwq.v;
50     };
51 };
52 priority_queue<ahh,vector<ahh>,cmp>q;
53 int d[11*MAXN];
54 bool sf[11*MAXN];
55 int main()
56 {
57     //freopen("a.in","r",stdin);
58     int m;
59     scanf("%d%d%d",&n,&m,&k);
60     int s,t;
61     scanf("%d%d",&s,&t);
62     for(int i=1;i<=m;++i)
63     {
64         int x,y,l;
65         scanf("%d%d%d",&x,&y,&l);
66         add(x,y,l);
67     }
68     t=k*n+t;
69     //cout<<s<<" "<<t<<endl;
70     memset(d,127,sizeof(d));
71     d[s]=0;
72     q.push((ahh){s,0});
73     while(!q.empty())
74     {
75         int x;
76         do{x=q.top().nod;q.pop();}while(sf[x]&&!q.empty());
77         sf[x]=1;
78         for(int i=h[x];i;i=a[i].f)
79         if(d[a[i].e]>d[x]+a[i].l)
80         {
81             d[a[i].e]=d[x]+a[i].l;
82             q.push((ahh){a[i].e,d[a[i].e]});
83         }
84     }
85     cout<<d[t];
86     return 0;
87 }

原文地址:https://www.cnblogs.com/qwerta/p/9898832.html

时间: 2024-10-30 07:46:15

「JLOI2011」「LuoguP4568」飞行路线(分层图最短路的相关文章

P4568 飞行路线 分层图最短路

P4568 飞行路线 分层图最短路 分层图最短路 问题模型 求最短路时,可有\(k\)次更改边权(减为0) 思路 在普通求\(Dijkstra\)基础上,\(dis[x][j]\)多开一维\(j\)以存已用了多少次机会,然后每次松弛时,做完普通松弛操作后,还要使用一次机会(如果可以),类同\(DP\). 每次普通松弛: \[ dis[to][j]=min\{dis[cur][j], dis[to][j]\} \] 如果还可以使用(\(j<k\)): \[ dis[to][j+1] = min\{

[P4568][JLOI2011] 飞行路线 (分层图+最短路)

题意:有n个城市,m条航线,每条航线都有一个权值,并且还多了k次免费航行的机会,求1~n的最短路: 做法:分层图+最短路: 1.分层图:因为多了k次免费航行,所以可以考虑建出k+1个图,然后跑一遍最短路: 2.最短路:既然能写分层图,那么最短路应该都会了吧,可以用 dijkstra 或 SPFA : 附上代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm>

P4568 [JLOI2011]飞行路线 &amp;&amp; 分层图最短路板子

目录说:我在右边 什么是分层图最短路: 分层图最短路是指在可以进行分层图的图上解决最短路问题. 一般模型是: 在图上,有k次机会可以直接通过一条边(权值为0),问起点与终点之间的最短路径. 解决的一般思路: 以这个题为例,给出了k次可以免费通过一个点的机会, 我们可以把原来的图垒在一起; ex: k = 1 1 2 3 2 3 4 3 1 2 4 2 1 4 3 6 我们在建完图之后再加上图中权值为0的边,很明显的分成了两层(若k = 1). 如果上边的那一层走到了下边,那就说明用了一次免费的机

BZOJ 2763 JLOI 2011 飞行路线 分层图+最短路

题目大意:两个小屁孩要乘飞机去旅行.现在给一些无向边和边权,另外他们还有K次免费乘坐飞机的机会,问从起点到终点的最小话费是什么. 思路:分层图第一题.之前听到分层图还以为是真的建K个图,然后不同层数之间的点连边跑最短路..后来经同学讲解才发现我想多了.. 其实还是动归的思想(最短路不也是动归的思想么(`?ω?′)),f[ i ][ j ]表示在j位置时,已经用了i次免费机会的时候的最小花费,然后在SPFA里多一维的转移就可以了. PS:BZOJ上这个题还是挺卡常数的,我之前用queue用了938

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

2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2523  Solved: 946[Submit][Status][Discuss] Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Alice和Bob现在要从一个城市沿着航线到达另一个城市

bzoj2763: [JLOI2011]飞行路线(分层图spfa)

2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3234  Solved: 1235[Submit][Status][Discuss] Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Alice和Bob现在要从一个城市沿着航线到达另一个城

poj3635Full Tank?[分层图最短路]

Full Tank? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7248   Accepted: 2338 Description After going through the receipts from your car trip through Europe this summer, you realised that the gas prices varied between the cities you v

BZOJ 2763 分层图最短路

突然发现我不会分层图最短路,写一发. 就是同层中用双向边相连,用单向边连下一层 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <string> 5 #include <cstring> 6 #include <queue> 7 #include <vector> 8 #define pa pair<int,int

HDU 5669 Road(线段树建树)(分层图最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5669 [分析]线段树建树+分层图最短路 #include <cstdio> #include <map> #include <algorithm> #include <vector> #include <iostream> #include <set> #include <queue> #include <string&

【网络流24题】 No.14 孤岛营救问题 (分层图最短路)

[题意] 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛, 营救被敌军俘虏的大兵瑞恩. 瑞恩被关押在一个迷宫里, 迷宫地形复杂, 但幸好麦克得到了迷宫的地形图. 迷宫的外形是一个长方形, 其南北方向被划分为 N 行,东西方向被划分为 M 列,于是整个迷宫被划分为 N× M 个单元.每一个单元的位置可用一个有序数对(单元的行号,单元的列号)来表示.南北或东西方向相邻的 2 个单元之间可能互通, 也可能有一扇锁着的门,或者是一堵不可逾越的墙.迷宫中有一些单元存放着钥匙, 并