• [JLOI2011]飞行路线 最短路


    题面

    题面

    题解

    这题不是很难,因为删代价的次数不多,因此我们只需要将最短路中的状态加一维表示已经删了几次,再转移即可

    #include<bits/stdc++.h>
    using namespace std;
    #define R register int
    #define AC 11000
    #define ac 130000
    
    int n, m, k, s, t, ans = 1000000000;
    int Head[AC], date[ac], Next[ac], len[ac], tot;
    int dis[AC][15];
    bool vis[AC][15];
    
    struct node{int x, dis, cost;};//编号 + 已经经过的距离 + 已经消耗的次数
    struct cmp{bool operator () (node a, node b){return a.dis > b.dis;}};
    priority_queue <node, vector<node>, cmp> q;
    
    inline int read()
    {
        int x = 0;char c = getchar();
        while(c > '9' || c < '0') c = getchar();
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x;
    }
    
    inline void upmin(int &a, int b) {if(b < a) a = b;}
    
    inline void add(int f, int w, int S)
    {
        date[++ tot] = w, Next[tot] = Head[f], Head[f] = tot, len[tot] = S;
        date[++ tot] = f, Next[tot] = Head[w], Head[w] = tot, len[tot] = S;
    }
    
    void pre()
    {
        n = read(), m = read(), k = read();
        s = read() + 1, t = read() + 1;
        for(R i = 1; i <= m; i ++) 
        {
            int x = read() + 1, y = read() + 1, S = read();
            add(x, y, S);
        }
    }
    
    void dij()
    {
        memset(dis, 127, sizeof(dis)), dis[s][0] = 0;
        q.push((node){s, 0, 0});
        while(!q.empty())
        {
            node x = q.top();
            q.pop();
            while(!q.empty() && vis[x.x][x.cost]) x = q.top(), q.pop();
            if(vis[x.x][x.cost]) break;
            vis[x.x][x.cost] = true;
            for(R i = Head[x.x]; i; i = Next[i])
            {
                int now = date[i];
                if(dis[now][x.cost] > dis[x.x][x.cost] + len[i])//不使用机会
                {
                    dis[now][x.cost] = dis[x.x][x.cost] + len[i];
                    q.push((node){now, dis[now][x.cost], x.cost});
                }
                if(x.cost < k && dis[now][x.cost + 1] > dis[x.x][x.cost])
                {
                    dis[now][x.cost + 1] = dis[x.x][x.cost];
                    q.push((node){now, dis[now][x.cost + 1], x.cost + 1});
                }
            }
        }
        for(R i = 0; i <= k; i ++) upmin(ans, dis[t][i]);
        printf("%d
    ", ans);
    }
    
    int main()
    {
    //	freopen("in.in", "r", stdin);
        pre();
        dij();
    //	fclose(stdin);
        return 0;
    }
    
  • 相关阅读:
    10. 正则表达式匹配
    124. 二叉树中的最大路径和。 递归
    1028. 从先序遍历还原二叉树。 深搜
    1014. 最佳观光组合. 转变思路
    297. 二叉树的序列化与反序列化.
    1300. 转变数组后最接近目标值的数组和. 二分
    15. 三数之和. 双指针法⭐
    1. 两数之和. 哈希表
    739. Daily Temperatures. 单调栈
    面试题46. 把数字翻译成字符串. 递归
  • 原文地址:https://www.cnblogs.com/ww3113306/p/10354363.html
Copyright © 2020-2023  润新知