[模板/题解]luogu_P4568_飞行路线(分层图最短路

 我们可能遇到这样的图论模型:在一个正常的图上可以进行 k 次决策,对于每次决策,不影响图的结构,只影响目前的状态或代价。同时这个图论模型和经典的最短路有关,这样我们可以考虑运用分层图最短路。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=10009;
const int maxm=50009;
int n,m,k,s,t;
struct node{
    int v,nxt,w;
}e[maxm<<1];
int head[maxn],cnt;
inline void add(int u,int v,int w){
    e[++cnt].v=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt;
}
int dis[maxn][11];
bool v[maxn][11];
struct poi{
    int x,w,cnt;//cnt使用次数 
    poi(){}
    poi(int xx,int ww,int cntt){
        x=xx;w=ww;cnt=cntt;
    }
    bool operator <(const poi &a)const{
        return w>a.w;
    }
};
priority_queue<poi> q;

void dij(int s){
    memset(dis,0x7f,sizeof(dis));
    dis[s][0]=0;
    q.push(poi(s,0,0));
    while(!q.empty()){
        poi p=q.top();q.pop();
        int x=p.x,cnt=p.cnt;
        if(v[x][cnt])continue;
        v[x][cnt]=1;
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v,w=e[i].w;
            if(cnt<k && dis[y][cnt+1]>dis[x][cnt]){
                dis[y][cnt+1]=dis[x][cnt];
                q.push(poi(y,dis[y][cnt+1],cnt+1));
            }
            if(dis[y][cnt]>dis[x][cnt]+w){
                dis[y][cnt]=dis[x][cnt]+w;
                q.push(poi(y,dis[y][cnt],cnt));
            }
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    scanf("%d%d",&s,&t);s++,t++;
    for(int i=1,u,v,w;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);v++,u++;
        add(u,v,w);add(v,u,w);
    }
    
    dij(s);int ans=2000000000;
    for(int i=0;i<=k;i++)
    ans=min(ans,dis[t][i]);
    printf("%d",ans);
//    for(int j=1;j<=n;j++)
//    for(int i=0;i<=k;i++)printf("%d
",dis[j][i]);
}
原文地址:https://www.cnblogs.com/superminivan/p/11448544.html