SSL2677 2017年8月10号提高组T2 飞行(spfa)

来源:互联网 发布:百川环评工程师软件 编辑:程序博客网 时间:2024/06/01 08:34

2017年8月10号提高组T2 飞行

Description

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

Input

第一行三个整数n,m,k,分别表示城市数量,航线数量和免费搭乘的航线数量。
第二行两个整数s,t,表示起点和终点。
接下来m行,每行三个整数a.b.c,表示一种航线,即可以从a到b,也可以从b到a,花费为c。

Output

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

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

代码

#include <cstdio>#define maxn 200000using namespace std;struct arr{    int x,y,z,nxt;}a[maxn];int ls[maxn],q[2000000][2],d[maxn][20];int l,n,m,k,s,t;bool v[maxn][20];void add(int p,int q,int o){    l++;    a[l].x=p;    a[l].y=q;    a[l].z=o;    a[l].nxt=ls[p];    ls[p]=l;}void spfa(){    int head=0,tail=1;    q[1][0]=s;    q[1][1]=0;    for (int i=0;i<=n;i++)        for (int j=0;j<=k;j++)            d[i][j]=123456789;    d[s][0]=0;    v[s][0]=true;    while (head<tail)    {        head++;        int u=q[head][0];        for (int i=ls[u];i;i=a[i].nxt)        {            if (d[u][q[head][1]]+a[i].z<d[a[i].y][q[head][1]])            {                d[a[i].y][q[head][1]]=d[u][q[head][1]]+a[i].z;                if (!v[a[i].y][q[head][1]])                {                    v[a[i].y][q[head][1]]=true;                    tail++;                    q[tail][0]=a[i].y;                    q[tail][1]=q[head][1];                }            }            if (d[u][q[head][1]]<d[a[i].y][q[head][1]+1]&&q[head][1]<k)            {                d[a[i].y][q[head][1]+1]=d[u][q[head][1]];                if (!v[a[i].y][q[head][1]+1])                {                    v[a[i].y][q[head][1]+1]=true;                    tail++;                    q[tail][0]=a[i].y;                    q[tail][1]=q[head][1]+1;                }            }        }        v[u][q[head][1]]=false;    }    int ans=123456789;    for (int i=0;i<=k;i++)        if (d[t][i]<ans) ans=d[t][i];    printf("%d",ans);}int main(){    scanf("%d%d%d",&n,&m,&k);    scanf("%d%d",&s,&t);    for (int i=1;i<=m;i++)    {        int p,q,o;        scanf("%d%d%d",&p,&q,&o);        add(p,q,o);        add(q,p,o);    }    spfa();}
原创粉丝点击