题目描述
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在 nnn 个城市设有业务,设这些城市分别标记为 000 到 n−1n-1n−1 ,一共有 mmm 种航线,每种航线连接两个城市,并且航线有一定的价格。
Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多 kkk 种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
输入输出格式
输入格式:数据的第一行有三个整数, n,m,kn,m,kn,m,k ,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数, s,ts,ts,t ,分别表示他们出行的起点城市编号和终点城市编号。
接下来有m行,每行三个整数, a,b,ca,b,ca,b,c ,表示存在一种航线,能从城市 aaa 到达城市 bbb ,或从城市 bbb 到达城市 aaa ,价格为 ccc 。
只有一行,包含一个整数,为最少花费。
输入输出样例
输入样例#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≤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
Solution:
本题板子,分层图+最短路。
对于免费的乘坐机会,等价于使得某条无向边变为0,由于只有10次免费机会,那么最多分10层图,各层的图都对应原图,层数代表着消耗的免费次数,当前层的每条边都可以连有向边指向下一层对应的节点且边权为0,这样去跑最短路,最后只需要统计各层终点的最小值就好了。
代码:
/*Code by 520 -- 8.21*/ #include<bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/priority_queue.hpp> #define il inline #define ll long long #define RE register #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++) #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--) using namespace std; using namespace __gnu_pbds; const int N=3000005,inf=0x7fffffff; struct node{ int u,d; bool operator <(const node &a)const {return d>a.d;} }; typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap; heap q; heap::point_iterator id[N]; int n,m,k,s,t,dis[N],ans=inf; int to[N],net[N],h[N],w[N],cnt; int gi(){ int a=0;char x=getchar(); while(x<'0'||x>'9')x=getchar(); while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+(x^48),x=getchar(); return a; } il void add(int u,int v,int c){ For(i,0,k) { to[++cnt]=v+i*n,net[cnt]=h[u+i*n],w[cnt]=c,h[u+i*n]=cnt; to[++cnt]=u+i*n,net[cnt]=h[v+i*n],w[cnt]=c,h[v+i*n]=cnt; if(i) { to[++cnt]=v+i*n,net[cnt]=h[u+(i-1)*n],w[cnt]=0,h[u+(i-1)*n]=cnt; to[++cnt]=u+i*n,net[cnt]=h[v+(i-1)*n],w[cnt]=0,h[v+(i-1)*n]=cnt; } } } il void dij(){ memset(dis,127,sizeof(dis)); dis[s]=0,q.push(node({s,0})); while(!q.empty()){ node x=q.top();q.pop(); for(RE int i=h[x.u];i;i=net[i]) if(dis[to[i]]>dis[x.u]+w[i]){ dis[to[i]]=dis[x.u]+w[i]; if(id[to[i]]==0) id[to[i]]=q.push(node({to[i],dis[to[i]]})); else q.modify(id[to[i]],node({to[i],dis[to[i]]})); } } } il void init(){ n=gi(),m=gi(),k=gi(),s=gi(),t=gi(); int u,v,c; while(m--) u=gi(),v=gi(),c=gi(),add(u,v,c); dij(); For(i,0,k) ans=min(ans,dis[t+i*n]); cout<<ans; } int main(){ init(); return 0; }