zoukankan      html  css  js  c++  java
  • 洛谷 P4568 [JLOI2011]飞行路线 解题报告

    P4568 [JLOI2011]飞行路线

    题目描述

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在(n)个城市设有业务,设这些城市分别标记为0到(n−1) ,一共有(m)种航线,每种航线连接两个城市,并且航线有一定的价格。

    Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多(k)种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    输入输出格式

    输入格式:

    数据的第一行有三个整数,(n,m,k),分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,(s,t),分别表示他们出行的起点城市编号和终点城市编号。
    接下来有(m)行,每行三个整数, (a,b,c),表示存在一种航线,能从城市(a)到达城市(b),或从城市(b)到达城市(a),价格为(c)

    输出格式:

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


    这是一个分层图+最短路的题目

    一种做法是按深度建图+向更深的图连0边,但这里讨论类似于DP的一种思想。

    (dis[i][j])代表节点(i)在深度为(j)的时候的最短路。

    按找dijk的思想进行三角形不等式松弛即可

    据说这个题卡SPFA

    实现看代码吧,我感觉挺好理解的。


    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N=10010;
    const int M=50010;
    int head[N],cnt=0,to[M<<1],next[M<<1],edge[M<<1];
    void add(int u,int v,int w)
    {
        to[++cnt]=v;next[cnt]=head[u];edge[cnt]=w;head[u]=cnt;
    }
    struct node
    {
        int i,dep,w;
        bool friend operator <(node n1,node n2)
        {
            return n1.w>n2.w;
        }
        node(){}
        node(int i,int dep,int w)
        {
            this->i=i;
            this->dep=dep;
            this->w=w;
        }
    };
    priority_queue <node> q;
    int dis[N][12],used[N][12],n,m,k,s,t;
    void dijk()
    {
        memset(dis,0x3f,sizeof(dis));
        dis[s][0]=0;
        node tt(s,0,dis[s][0]);
        q.push(tt);
        while(!q.empty())
        {
            node from=q.top();
            q.pop();
            int dep=from.dep,u=from.i;
            if(used[u][dep]) continue;
            used[u][dep]=1;
            for(int i=head[u];i;i=next[i])
            {
                int v=to[i],w=edge[i];
                if(!used[v][dep]&&dis[v][dep]>dis[u][dep]+w)
                {
                    dis[v][dep]=dis[u][dep]+w;
                    node tt(v,dep,dis[v][dep]);
                    q.push(tt);
                }
                if(dep<k&&!used[v][dep+1]&&dis[v][dep+1]>dis[u][dep])
                {
                    dis[v][dep+1]=dis[u][dep];
                    node tt(v,dep+1,dis[v][dep+1]);
                    q.push(tt);
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
        int u,v,w;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w),add(v,u,w);
        }
        dijk();
        printf("%d
    ",dis[t][k]);
        return 0;
    }
    
    

    2018.6.20

  • 相关阅读:
    poj2104 Kth-Number
    bzoj2120 数颜色
    hdu5145 NPY and girls
    bzoj2734 集合选数
    bzoj3732 NetWork
    bzoj2152 聪聪可可
    hdu2036(多边形面积)
    超大次幂思路
    hdu 2030 统计汉字个数
    Hibernate 配置文件与映射文件 总结
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9205407.html
Copyright © 2011-2022 走看看