题目描述
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在nn个城市设有业务,设这些城市分别标记为00到n-1n−1,一共有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。
输出格式:
只有一行,包含一个整数,为最少花费。
输入输出样例
分为k+1层即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=1e6; const int M=1e8; int head[M]; int pos; struct node { int v,to,nex; }edge[M]; void add(int a,int b,int c) { edge[++pos].nex=head[a]; head[a]=pos; edge[pos].v=c; edge[pos].to=b; } struct Node { int d,id; bool operator<(const Node& b)const { return d>b.d; } }; int dis[N],vis[N]; int n,m,k,a,b,c,s,t; void dijkstra(int s) { CLR(dis,0x3f); dis[s]=0; priority_queue<Node>q; q.push(Node{0,s}); while(!q.empty()) { Node u=q.top();q.pop(); if(vis[u.id])continue; vis[u.id]=1; for(int i=head[u.id];i;i=edge[i].nex) { int v=edge[i].to; if(u.d+edge[i].v<dis[v]) { dis[v]=u.d+edge[i].v; q.push(Node{dis[v],v}); } } } } int main() { RIII(n,m,k); RII(s,t);s++;t++; rep(i,1,m) { RIII(a,b,c);a++;b++; add(a,b,c);add(b,a,c); rep(j,1,k) { add(j*n+a,j*n+b,c); add(j*n+b,j*n+a,c); add((j-1)*n+a,j*n+b,0); add((j-1)*n+b,j*n+a,0); } } dijkstra(s); int ans=dis[t]; rep(i,1,k) ans=min(ans,dis[t+i*n]); cout<<ans; return 0; }