• 二维spfa [JLOI2011]飞行路线


    问题 D: [JLOI2011]飞行路线

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 151  解决: 32
    [提交][状态][讨论版]

    题目描述

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    输入

    数据的第一行有三个整数,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)
     

    输出

     
    只有一行,包含一个整数,为最少花费。

    样例输入

    5 6 10 40 1 51 2 52 3 53 4 52 3 30 2 100

    样例输出

    8

    提示

    对于30%的数据,2<=n<=50,1<=m<=300,k=0;

    对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

    对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

      就是普通二维spfa,复习下板子。对了,要用堆优化,而且重载时符号别重载反。。
      
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define N 10000
    using namespace std;
    int read()
    {
        int sum=0,f=1;char x=getchar();
        while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
        while(x>='0'&&x<='9'){sum=sum*10+x-'0';x=getchar();}
        return sum*f;
    }
    int n,m,k,adj[N+5],v[N+5][15];
    int dis[N+5][15],e,s,t,ans=(1<<30);
    struct road
    {
        int v,next,l;
    }lu[N*10+5]; 
    struct node
    {
        int id,h,dis;
        node(){}
        node(int x,int y,int z)
        {
            id=x;h=y;dis=z;
        }
        bool friend operator <(const node &a,const node &b)
        {
            return (a.dis!=b.dis)? (a.dis>b.dis):(a.h>b.h);
        }
    };
    priority_queue<node> q;
    void add(int u,int v,int l){lu[++e].v=v;lu[e].next=adj[u];lu[e].l=l;adj[u]=e;}
    void spfa()
    {
        dis[s][0]=0;v[s][0]=1;
        q.push(node(s,0,0));
        while(!q.empty())
        {
            node w=q.top();q.pop();int tmp=w.h,x=w.id;
            for(int i=adj[x];i;i=lu[i].next)
            {
                int to=lu[i].v;
                if(dis[to][tmp]>dis[x][tmp]+lu[i].l)
                {
                    dis[to][tmp]=dis[x][tmp]+lu[i].l;
                    if(!v[to][tmp])
                    {
                        v[to][tmp]=1;
                        q.push(node(to,tmp,dis[to][tmp]));
                    }
                }
                if(tmp<k&&dis[to][tmp+1]>dis[x][tmp])
                {
                    dis[to][tmp+1]=dis[x][tmp];
                    if(!v[to][tmp+1])
                    {
                        v[to][tmp+1]=1;
                        q.push(node(to,tmp+1,dis[to][tmp+1]));
                    }
                }
            }
            v[x][tmp]=0;
        }
    }
    int main()
    {
        n=read();m=read();k=read();s=read();t=read();
        int x,y,z;
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();z=read();
            add(x,y,z);
            add(y,x,z);
        }
        memset(dis,120,sizeof(dis));
        spfa();
        for(int i=0;i<=k;i++)
           ans=min(ans,dis[t][i]);
        cout<<ans;
    }

  • 相关阅读:
    常见的消息队列中间件介绍
    关系型数据库和非关系型数据库区别、oracle与mysql的区别
    SQL Server 和 Oracle 以及 MySQL 数据库
    Redis,Memcache,MongoDb的特点与区别
    详解布隆过滤器的原理,使用场景和注意事项
    Redis缓存穿透、缓存击穿以及缓存雪崩
    RPC、HTTP、RESTful
    集群,分布式,微服务概念和区别理解
    电脑双屏变单屏后,界面显示问题
    JDK 15已发布,你所要知道的都在这里!
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632719.html
Copyright © 2020-2023  润新知