洛谷 P4568 [JLOI2011]飞行路线

题目传送门

分层图最短路,或者说是一个DP,f[i][j]表示用了i张免费券,到了j号点的最小花费,然后跑最短路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

int n,m,k,s,t,tot,dis[15][10005],ans = 2100000000,head[10005];
bool vis[15][10005];
struct kkk {
    int v,next,to;
}e[100005];
struct node {
    int level,id,dist;
    bool operator <(const node &a) const {
        return dist > a.dist;
    }
};
priority_queue<node> q;

inline void add(int x,int y,int z) {
    e[++tot].to = y;
    e[tot].v = z;
    e[tot].next = head[x];
    head[x] = tot;
}

inline node cc(int l,int r,int w) {
    node pp;
    pp.dist = w;
    pp.id = r;
    pp.level = l;
    return pp;
}

inline void dijkstra() {
    memset(dis,0x3f3f3f,sizeof(dis));
    dis[0][s] = 0;
    q.push(cc(0,s,0));
    while(!q.empty()) {
        int u = q.top().level;
        int o = q.top().id;
        q.pop();
        if(vis[u][o]) continue;
        vis[u][o] = 1;
        for(int i = head[o];i; i = e[i].next) {
            int vv = e[i].v;
            int w = e[i].to;
            if(dis[u][o] + vv < dis[u][w]) {
                dis[u][w] = dis[u][o] + vv;
                q.push(cc(u,w,dis[u][w]));
            }
            if(dis[u+1][w] > dis[u][o] && u < k) {
                dis[u+1][w] = dis[u][o];
                q.push(cc(u + 1,w,dis[u+1][w]));
            }
        }
    }
}

int main() {
    scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
    for(int i = 1;i <= m; i++) {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    dijkstra();
    for(int i = 0;i <= k; i++)
        ans = min(ans,dis[i][t]);
    printf("%d",ans);
    return 0;
} 

 

posted @ 2020-09-02 21:14  Mr^Simon  阅读(166)  评论(0编辑  收藏  举报