[JLOI2011]飞行路线

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.

建立分层图。
f[u][t]表示在节点u时已经免费乘坐t次的最少花
费。照样跑最短路。
枚举与u相连的所有节点v,w(u,v)表示权值。
若t<k:
f[v][t+1]=min(f[v][t+1],f[u][t])
对于所有:
f[v][t]=min(f[v][t],f[u][t]+w(u,v))

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 struct Node
 8 {
 9   int next,to,dis;
10 }edge[100001];
11 struct XXX
12 {
13   int x;
14   int k;
15 };
16 int num,head[100001],dist[100001][11],n,m,k,S,T,ans;
17 bool vis[100001][11];
18 void add(int u,int v,int d)
19 {
20   num++;
21   edge[num].next=head[u];
22   head[u]=num;
23   edge[num].to=v;
24   edge[num].dis=d;
25 }
26 void SPFA()
27 {int i;
28   queue<XXX> Q;
29   Q.push((XXX){S,0});
30   dist[S][0]=0;
31   while (Q.empty()==0)
32   {
33     XXX u=Q.front();
34     Q.pop();
35     vis[u.x][u.k]=0;
36     for (i=head[u.x];i;i=edge[i].next)
37       {int v=edge[i].to;
38     if (dist[v][u.k]>dist[u.x][u.k]+edge[i].dis)
39       {
40         dist[v][u.k]=dist[u.x][u.k]+edge[i].dis;
41         if (vis[v][u.k]==0)
42           {
43         vis[v][u.k]=1;
44         Q.push((XXX){v,u.k});
45           }
46       }
47     if (u.k+1<=k&&dist[v][u.k+1]>dist[u.x][u.k])
48       {
49         dist[v][u.k+1]=dist[u.x][u.k];
50         if (vis[v][u.k+1]==0)
51           {
52         vis[v][u.k+1]=1;
53         Q.push((XXX){v,u.k+1});
54           }
55       }
56       }
57   }
58 }
59 int main()
60 {int i,u,v,c;
61   cin>>n>>m>>k;
62   memset(dist,127/3,sizeof(dist));
63   scanf("%d%d",&S,&T);
64   for (i=1;i<=m;i++)
65     {
66       scanf("%d%d%d",&u,&v,&c);
67       add(u,v,c);
68       add(v,u,c);
69     }
70   SPFA();
71   ans=2e9;
72   for (i=0;i<=k;i++)
73     ans=min(ans,dist[T][i]);
74   cout<<ans;
75 }
原文地址:https://www.cnblogs.com/Y-E-T-I/p/7473260.html