bzoj2763 [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
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.
正解:分层图最短路。
原来这就是所谓分层图最短路,还以为多么高级呢。。
直接跑spfa即可,爆状态那么用循环队列,$TLE$那么交换枚举状态,先松弛不免费的,再松弛免费的。
1 //It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #define inf (1<<30) 14 #define N (10010) 15 #define il inline 16 #define RG register 17 #define ll long long 18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 19 20 using namespace std; 21 22 struct edge{ int nt,to,dis; }g[20*N]; 23 struct data{ int x,k; }q[20*N]; 24 25 int head[N],dis[N][12],vis[N][12],S,T,n,m,k,num,size=200000; 26 27 il int gi(){ 28 RG int x=0,q=1; RG char ch=getchar(); 29 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 30 if (ch=='-') q=-1,ch=getchar(); 31 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 32 return q*x; 33 } 34 35 il void insert(RG int from,RG int to,RG int dis){ 36 g[++num]=(edge){head[from],to,dis},head[from]=num; return; 37 } 38 39 il void spfa(){ 40 memset(dis,0x3f3f3f,sizeof(dis)); 41 RG int h=0,t=1; q[t]=(data){S,0},dis[S][0]=0,vis[S][0]=1; 42 while (h!=t){ 43 ++h; if (h>size) h=1; RG data x=q[h]; RG int v; 44 for (RG int i=head[x.x];i;i=g[i].nt){ 45 v=g[i].to; 46 if (dis[v][x.k]>dis[x.x][x.k]+g[i].dis){ 47 dis[v][x.k]=dis[x.x][x.k]+g[i].dis; 48 if (!vis[v][x.k]){ 49 ++t; if (t>size) t=1; 50 q[t]=(data){v,x.k},vis[v][x.k]=1; 51 } 52 } 53 if (x.k+1<=k && dis[v][x.k+1]>dis[x.x][x.k]){ 54 dis[v][x.k+1]=dis[x.x][x.k]; 55 if (!vis[v][x.k+1]){ 56 ++t; if (t>size) t=1; 57 q[t]=(data){v,x.k+1},vis[v][x.k+1]=1; 58 } 59 } 60 } 61 vis[x.x][x.k]=0; 62 } 63 return; 64 } 65 66 il void work(){ 67 n=gi(),m=gi(),k=gi(),S=gi()+1,T=gi()+1; 68 for (RG int i=1,u,v,w;i<=m;++i) 69 u=gi()+1,v=gi()+1,w=gi(),insert(u,v,w),insert(v,u,w); 70 spfa(),printf("%d\n",dis[T][k]); return; 71 } 72 73 int main(){ 74 File("flight"); 75 work(); 76 return 0; 77 }