zoukankan      html  css  js  c++  java
  • 最短路——分层图最短路

    模板题:https://www.luogu.com.cn/problem/P4568

    题目描述

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

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

    输入格式

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

    接下来一行两个整数 s,t分别表示他们出行的起点城市编号和终点城市编号。

    接下来 mm行,每行三个整数a,b,c表示存在一种航线,能从城市 aa到达城市 b,或从城市 b 到达城市 a,价格为 c。

    输出格式

    输出一行一个整数,为最少花费。

    题解:对于n个结点的图看成是一层,这里可以省略k次航线路费。那么就可以i看作是k+1层的图,每一层都是n个结点,第0层表示较少了0次花费,第i层表示减少了i次花费。所以disi,j=min{min{disfrom,j1},min{disfrom,j+w}}

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e4+10;
    const int M=5e4+10;
    struct st{
        int from,to,next,dis;
    }edge[M*2];
    int n,m,k,head[N],cnt;
    int dis[N][11];
    struct node{
        int u,j,dis;
        node(int a=0,int b=0,int c=0):u(a),j(b),dis(c){}
        bool operator>(const struct node a1)const {
            return dis>a1.dis;
        }
    };
    void addedge(int u,int v,int w){
        cnt++;
        edge[cnt].from=u;
        edge[cnt].to=v;
        edge[cnt].dis=w;
        edge[cnt].next=head[u];
        head[u]=cnt;
    }
    void dijkstra(int s){
        memset(dis,0x3f,sizeof(dis));
        int vis[N][11];
        memset(vis,0,sizeof(vis));
        priority_queue<struct node ,vector<struct node>,greater<struct node> >q;
        struct node a1;
        q.push(node(s,0,0));
        while(!q.empty()){
            a1=q.top();q.pop();
            if(vis[a1.u][a1.j]==1) continue;
            vis[a1.u][a1.j]=1;
            dis[a1.u][a1.j]=a1.dis;
            for(int i=head[a1.u];i;i=edge[i].next){
                if(vis[edge[i].to][a1.j]==1) ;
                else {
                    q.push(node(edge[i].to,a1.j,a1.dis+edge[i].dis));
                }
                if(vis[edge[i].to][a1.j+1]==1||a1.j+1>k) ;
                else {
                    q.push(node(edge[i].to,a1.j+1,a1.dis));
                }
            }
        }
    }
    int main(){
        cin>>n>>m>>k;
        int s,t;
        cin>>s>>t;
        for(int i=1,a,b,c;i<=m;i++){
            cin>>a>>b>>c;
            addedge(a,b,c);
            addedge(b,a,c);
        }
        dijkstra(s);
        int ans=0x3f3f3f3f;
        for(int i=0;i<=k;i++){
            ans=min(ans,dis[t][i]);
        } 
        cout<<ans<<endl;
        return 0;
    }

    写于2020/8/11 23:25


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    BZOJ 4886 Lydsy1705月赛 叠塔游戏
    BZOJ 4552 TJOI2016&&HEOI2016 排序
    BZOJ 3702 二叉树
    BZOJ 4756 Usaco2017 Jan Promotion Counting
    BZOJ 4842 Neerc2016 Delight for a Cat
    BZOJ 1283 序列
    BZOJ 4819 SDOI2017 新生舞会
    BZOJ 1531 POI2005 Bank notes
    BZOJ 1925 SDOI2010 地精部落
    BZOJ WC2006 水管局长数据加强版
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13488042.html
Copyright © 2011-2022 走看看