您的位置:首页 > 编程语言 > C语言/C++

【SSLGZ 2677】2017年8月10号提高组T2 飞行

2017-08-12 17:01 483 查看
问题描述

有n个城市,编号为0到n-1。小B想从城市s到城市t。他们选择了一家航空公司,这家公司有m种航线,每种航线连接了两个不同的城市。看在小B是个妹子的份上,航空公司的老总给了小B一点优惠:小B可以免费在最多k种航线上搭乘飞机。问小B最小花费是多少。

输入

第一行三个整数n,m,k,分别表示城市数量,航线数量和免费搭乘的航线数量。

第二行两个整数s,t,表示起点和终点。

接下来m行,每行三个整数a.b.c,表示一种航线,即可以从a到b,也可以从b到a,花费为c。

输出

一行一个整数,表示最小花费。

样例输入

5 6 1

0 4

0 1 5

1 2 5

2 3 5

3 4 5

2 3 3

0 2 100

样例输出

8

算法讨论

分层图spfa,dis[i,j]表示从起点走到点i,用了j次优惠的最小费用。枚举是否用优惠往后转移即可。

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 100000
#define maxm 500000
struct edge
{
int f,t,n,c;
}a[maxm];
int ls[maxn],d[maxn][15],list[maxn];
bool v[maxn];
int n,m,k,s,t,e;

int init()
{
scanf("%d%d%d",&n,&m,&k);
scanf("%d%d",&s,&t);
for (int i=0;i<m;i++)
ls[i]=-1;
for (int i=1;i<=m;i++)
{
e++;
scanf("%d%d%d",&a[e].f,&a[e].t,&a[e].c);
a[e].n=ls[a[e].f];
ls[a[e].f]=e;
e++;
a[e].f=a[e-1].t; a[e].t=a[e-1].f; a[e].c=a[e-1].c;
a[e].n=ls[a[e].f];
ls[a[e].f]=e;
}
for (int i=0;i<n;i++)
for (int j=0;j<=k;j++)
d[i][j]=2147483647;
for (int j=0;j<=k;j++)
d[s][j]=0;
}

int spfa()
{
int hd=0,tl=0,t=0;
tl=1;
list[1]=s;
v[s]=1;
while (hd!=tl)
{
hd++;
t=ls[list[hd]];
while (t>-1)
{
for (int j=0;j<=k;j++)
if (d[a[t].f][j]+a[t].c<d[a[t].t][j] || d[a[t].f][j]<d[a[t].t][j+1])
{
d[a[t].t][j]=min(d[a[t].t][j],d[a[t].f][j]+a[t].c);
d[a[t].t][j+1]=min(d[a[t].t][j+1],d[a[t].f][j]);
if (!v[a[t].t])
{
v[a[t].t]=1;
tl++;
list[tl]=a[t].t;
}
}
t=a[t].n;
}
v[list[hd]]=0;
}
}

int main()
{
init();
spfa();
printf("%d",d[t][k]);
return 0;
}




Pixiv ID:33737282
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ spfa 分层图