[JLOI2011]飞行路线

来源:互联网 发布:ipad下载软件 编辑:程序博客网 时间:2024/05/16 04:47

提交:bzoj2763
题目↑↑

这道题是由tyb师兄讲的一道spfa

只要记录f[i][j]表示到第i个点用j次机会的最短路径即可

if(f[x][c]+a[k].d<f[y][c])//这种情况直接进行最短路{    f[y][c]=f[x][c]+a[k].d;    if(v[y][c]==false)    {        v[y][c]=true;        list[tail][0]=y;        list[tail][1]=c;        tail++;if(tail==100000+1) tail=1;    }}if(f[x][c]<f[y][c+1]&&c<kk)//如果可以使用免费机会就改变{    f[y][c+1]=f[x][c];    if(v[y][c+1]==false)    {        v[y][c+1]=true;        list[tail][0]=y;        list[tail][1]=c+1;        tail++;if(tail==100000+1) tail=1;    }}

代码↓↓

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>using namespace std;struct node{    int x,y,d,next;}a[110000];int len,last[51000];void ins(int x,int y,int d){    len++;    a[len].x=x;a[len].y=y;a[len].d=d;    a[len].next=last[x];last[x]=len;}int f[110000][11];bool v[110000][11];int n,m,kk;int st,ed;int list[110000][2];void spfa(){    int head=1,tail=2;    memset(list,0,sizeof(list));    list[1][0]=st;list[1][1]=0;    while(head!=tail)    {        int x=list[head][0],c=list[head][1];        for(int k=last[x];k;k=a[k].next)        {            int y=a[k].y;            if(f[x][c]+a[k].d<f[y][c])            {                f[y][c]=f[x][c]+a[k].d;                if(v[y][c]==false)                {                    v[y][c]=true;                    list[tail][0]=y;                    list[tail][1]=c;                    tail++;if(tail==100000+1) tail=1;                }            }            if(f[x][c]<f[y][c+1]&&c<kk)            {                f[y][c+1]=f[x][c];                if(v[y][c+1]==false)                {                    v[y][c+1]=true;                    list[tail][0]=y;                    list[tail][1]=c+1;                    tail++;if(tail==100000+1) tail=1;                }            }        }        head++;if(head==100000+1) head=1;        v[x][c]=false;    }}int main(){    scanf("%d%d%d",&n,&m,&kk);    scanf("%d%d",&st,&ed);    for(int i=1;i<=m;i++)    {        int x,y,d;        scanf("%d%d%d",&x,&y,&d);        ins(x,y,d);ins(y,x,d);    }    for(int i=0;i<=n;i++) for(int j=0;j<=kk;j++) f[i][j]=999999999;    memset(v,false,sizeof(v));v[st][0]=true;    f[st][0]=0;    spfa();    int mmin=999999999;    for(int i=0;i<=kk;i++) mmin=min(f[ed][i],mmin);    printf("%d\n",mmin);    return 0;}
0 0