最短路——分层图最短路

模板题: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

 

posted @ 2020-08-11 23:25  白菜茄子  阅读(178)  评论(0编辑  收藏  举报