[JLOI2011]飞行路线

题目描述

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

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

输入格式

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

输出格式

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

输入输出样例

输入 #1
5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100
【解题思路】
套路题,分层图。
【code】
 1 #include<cstdio>
 2 #include<cctype>
 3 #include<cstring>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<utility> 
 8 #include<functional>
 9 
10 int Read()
11 {
12     int x=0;char c=getchar();
13     while(!isdigit(c))
14     {
15         c=getchar();
16     }
17     while(isdigit(c))
18     {
19         x=x*10+(c^48);
20         c=getchar();
21     }
22     return x;
23 }
24 
25 using std::priority_queue;
26 using std::pair;
27 using std::vector;
28 using std::make_pair;
29 using std::greater;
30 
31 struct Edge
32 {
33     int to,next,cost;
34 }edge[2500001];
35 int cnt,head[110005];
36 
37 void add_edge(int u,int v,int c=0)
38 {
39     edge[++cnt]=(Edge){v,head[u],c};
40     head[u]=cnt;
41 }
42 
43 int dis[110005];
44 bool vis[110005];
45 void Dijkstra(int s)
46 {
47     memset(dis,0x3f,sizeof(dis));
48     dis[s]=0;
49     priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > points;
50     points.push(make_pair(0,s));
51     while(!points.empty())
52     {
53         int u=points.top().second;
54         points.pop();
55         if(!vis[u])
56         {
57             vis[u]=1;
58             for(int i=head[u];i;i=edge[i].next)
59             {
60                 int to=edge[i].to;
61                 if(dis[to]>dis[u]+edge[i].cost) 
62                 {
63                     dis[to]=dis[u]+edge[i].cost;
64                     points.push(make_pair(dis[to],to));
65                 }
66             }
67         }
68     }
69 }
70 
71 int main()
72 {
73     int n=Read(),m=Read(),k=Read(),s=Read(),t=Read();
74     int u,v,c;
75     for(int i=0;i<m;++i)
76     {
77         u=Read(),v=Read(),c=Read();
78         add_edge(u,v,c);
79         add_edge(v,u,c);
80         for(int j=1;j<=k;++j)
81         {
82             add_edge(u+(j-1)*n,v+j*n);
83             add_edge(v+(j-1)*n,u+j*n);
84             add_edge(u+j*n,v+j*n,c);
85             add_edge(v+j*n,u+j*n,c);
86         }
87     }
88     for(int i=1;i<=k;++i)
89     {
90         add_edge(t+(i-1)*n,t+i*n);
91     }//预防奇葩数据
92     Dijkstra(s);
93     printf("%d",dis[t+k*n]);
94     return 0;
95 }

 

posted @ 2019-09-17 23:29  GTR_PaulFrank  阅读(166)  评论(0编辑  收藏  举报