BZOJ 2763: [JLOI2011]飞行路线 【分层图模板】

任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2763

2763: [JLOI2011]飞行路线

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 4928  Solved: 1938
[Submit][Status][Discuss]

Description

Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

Input

数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
 

Output

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

Sample Input

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

Sample Output

8

HINT

 

对于30%的数据,2<=n<=50,1<=m<=300,k=0;


对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;


对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

 

 

Tip:模板用,用模板。

 

AC code:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <queue>
 6 #include <cstring>
 7 #define INF 0x3f3f3f3f
 8 #define LL long long int
 9 using namespace std;
10 const int MAX_M = 5e4+10;
11 const int MAX_N = 1e4+10;
12 const int MAX_K = 11;
13 struct date
14 {
15     int v, nxt, val;
16 }edge[MAX_M<<1];
17 
18 struct node
19 {
20     int u, k, w;
21     bool operator < (const node& a)const{
22         return w > a.w;
23     }
24 };
25 int N, M, K;
26 int head[MAX_N], cnt;
27 int dis[MAX_N][MAX_K];
28 bool vis[MAX_N][MAX_K];
29 priority_queue<node> Q;
30 
31 void init()
32 {
33     memset(head, -1, sizeof(head));
34     cnt = 1;
35 }
36 
37 void add(int from, int to, int weight)
38 {
39     edge[cnt].nxt = head[from];
40     edge[cnt].v = to;
41     edge[cnt].val = weight;
42     head[from] = cnt++;
43 }
44 
45 void Dijkstra(int s)
46 {
47     memset(dis, INF, sizeof(dis));
48     node tp; int v;
49     tp.u = s, tp.w = dis[s][0] = 0, tp.k = 0;
50     Q.push(tp);
51     vis[s][0] = true;
52     while(!Q.empty()){
53         tp = Q.top();Q.pop();
54         vis[tp.u][tp.k] = false;
55         for(int i = head[tp.u]; i != -1; i = edge[i].nxt){
56             v = edge[i].v;
57             if(dis[v][tp.k] > dis[tp.u][tp.k] + edge[i].val){
58                 dis[v][tp.k] = dis[tp.u][tp.k] + edge[i].val;
59                 if(!vis[v][tp.k]){
60                     Q.push(node{v, tp.k, dis[v][tp.k]});
61                     vis[v][tp.k] = true;
62                 }
63             }
64             if(tp.k+1 <= K){
65                 if(dis[v][tp.k+1] > dis[tp.u][tp.k]){
66                 dis[v][tp.k+1] = dis[tp.u][tp.k];
67                 if(!vis[v][tp.k+1]){
68                     Q.push(node{v, tp.k+1, dis[v][tp.k+1]});
69                     vis[v][tp.k+1] = true;
70                     }
71                 }
72             }
73         }
74     }
75 }
76 
77 int main()
78 {
79     int u, v, w, st, ed;
80     scanf("%d%d%d", &N, &M, &K);
81     scanf("%d%d", &st, &ed);
82     init();
83     for(int i = 1; i <= M; i++){
84         scanf("%d%d%d", &u, &v, &w);
85         add(u, v, w);
86         add(v, u, w);
87     }
88     Dijkstra(st);
89     printf("%d\n", dis[ed][K]);
90     return 0;
91 }

 

posted @ 2018-09-05 15:57  莜莫  阅读(207)  评论(0编辑  收藏  举报