1. 程式人生 > >[JLOI2011]飛行路線

[JLOI2011]飛行路線

出行 相對 n-1 nod 數據 連接 分層圖 family nbsp

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 }

[JLOI2011]飛行路線