1. 程式人生 > >「JLOI2011」「LuoguP4568」飛行路線(分層圖最短路

「JLOI2011」「LuoguP4568」飛行路線(分層圖最短路

題目描述

Alice和Bob現在要乘飛機旅行,他們選擇了一家相對便宜的航空公司。該航空公司一共在nn個城市設有業務,設這些城市分別標記為00到n-1n1,一共有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=02n50,1m300,k=0;
對於50%的資料,2 \le n \le 600,1 \le m \le 6000,0 \le k \le 12n600,1m6000,0k1;
對於100%的資料,2 \le n \le 10000,1 \le m \le 50000,0 \le k \le 102n10000,1m50000,0k10,0 \le s,t<n,0 \le a,b<n,a\neq b,0 \le c \le 10000s,t<n,0a,b<n,ab,0c1000

題解

建分層圖就好了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 }