2763: [JLOI2011]飞行路线
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3089 Solved: 1158
[Submit][Status][Discuss]
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.
Source
k很小,所以这显然是个分层图,有一个很类似的题——bzoj1614,但感觉很不一样,烧脑
sdfzgzk说可以只加两条边,然而蒟蒻的我没有听懂,所以只好推一个边数的大约上界去开数组了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 int n,m,k,s,e,cnt,ans; 8 struct data{ 9 int next,to,dis; 10 }edge[2500010]; 11 struct node{ 12 int x,dd; 13 }; 14 int head[1250010],w[1250010]; 15 bool check[1250010]; 16 priority_queue<node>q; 17 void add(int start,int end,int d){ 18 edge[++cnt].next=head[start]; 19 edge[cnt].to=end; 20 edge[cnt].dis=d; 21 head[start]=cnt; 22 } 23 bool operator<(node aa,node bb){ 24 if(aa.dd==bb.dd) return aa.x<bb.x; 25 return aa.dd>bb.dd; 26 } 27 void dijkstra(){ 28 memset(w,0x3f3f3f3f,sizeof(w)); 29 q.push((node){s,0}); 30 w[s]=0; 31 while(!q.empty()){ 32 node tmp=q.top(); 33 q.pop(); 34 if(check[tmp.x]) continue; 35 check[tmp.x]=1; 36 for(int i=head[tmp.x];i;i=edge[i].next) 37 if(w[edge[i].to]>w[tmp.x]+edge[i].dis){ 38 w[edge[i].to]=w[tmp.x]+edge[i].dis; 39 q.push((node){edge[i].to,w[edge[i].to]}); 40 } 41 } 42 } 43 int main(){ 44 scanf("%d%d%d%d%d",&n,&m,&k,&s,&e); 45 int x=0,y=0,z=0; 46 for(int i=1;i<=m;i++){ 47 scanf("%d%d%d",&x,&y,&z); 48 for(int j=0;j<=k;j++){ 49 add(x+j*n,y+j*n,z); 50 add(y+j*n,x+j*n,z); 51 if(j<k){ 52 add(x+j*n,y+(j+1)*n,0); 53 add(y+j*n,x+(j+1)*n,0); 54 } 55 } 56 } 57 dijkstra(); 58 ans=0x3f3f3f3f; 59 for(int i=0;i<=k;i++) ans=min(ans,w[e+i*n]); 60 printf("%d\n",ans); 61 return 0; 62 }
时间: 2024-12-21 04:21:22