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.
思路:
就是记录一下跑spfa 的时候,少走几条边时的最短距离。
#include<bits/stdc++.h>
using namespace std;
const int M = 1e5+1000;
const int N = 2e4+100;
const int INF = 0x3f3f3f3f;
typedef pair<int,int> P;
struct node{
int to,value,next;
}p[M];
bool inq[N][11];
int dis[N][15],head[M],cnt;
int n,m,k,s,t;
void Add(int u, int v, int w){
p[++cnt] = {v,w,head[u]};
head[u] = cnt;
return;
}
void init(){
int x,y,z;
memset(head,-1,sizeof(head));
cnt = -1;
scanf("%d%d%d",&n,&m,&k);
scanf("%d%d",&s, &t);
for (int i = 0; i < m; i++){
scanf("%d%d%d",&x,&y,&z);
Add(x,y,z);
Add(y,x,z);
}
return;
}
void spfa(){
memset(dis,INF,sizeof(dis));
queue<P>q;
q.push(P(s,0));
dis[s][0] = 0; inq[s][0] = 1;
while(!q.empty()){
int u = q.front().first;
int tmp = q.front().second; q.pop(); //tmp 是少走几条路。。
for (int i = head[u]; ~i; i = p[i].next){ // 正常操作。
int v = p[i].to;
if (dis[u][tmp] + p[i].value < dis[v][tmp]){
dis[v][tmp] = dis[u][tmp] + p[i].value;
if (!inq[v][tmp]){
inq[v][tmp] = 1;
q.push(P(v,tmp));
}
}
if (dis[u][tmp] < dis[v][tmp+1] && tmp < k){ //这里就是分层的操作了。
dis[v][tmp+1] = dis[u][tmp]; //当前点和下一个点。是不是可以少走一条边。
if (!inq[v][tmp+1]){
inq[v][tmp+1] = 1;
q.push(P(v,tmp+1));
}
}
}
inq[u][tmp] = 0;
}
int ans = INF;
for (int i = 0; i <= k; i++)
ans = min(ans,dis[t][i]);
printf("%d\n",ans);
return;
}
int main(){
init();
spfa();
return 0;
}
本文探讨了如何使用SPFA算法解决旅行中的成本优化问题,具体是在特定条件下找到从起点到终点的最低花费路径,考虑到免费乘坐特定数量航班的优惠。
901

被折叠的 条评论
为什么被折叠?



