• Solution 「Gym 101630J」Journey from Petersburg to Moscow


    \(\mathscr{Description}\)

      Link.

      给定含有 \(n\) 个点 \(m\) 条边的带权无向图,一条路径的长度定义为其中前 \(k\) 大的边权和,求 \(1\)\(n\) 的最短路。

      \(n,m,k\le3\times10^3\)

    \(\mathscr{Solution}\)

      模拟赛题,我对放 WQS 过了但其实大样例都没有凸性的造数据人表示 。

      先把正常的最短路作为答案上界,接下来我们只需要考虑路径中包含至少 \(k\) 条边的情况。算是一种构造,枚举第 \(k\) 大的边权 \(w_0\),令所有边权减去 \(w_0\) 并向 \(0\)\(\max\),用此时最短路的长度 \(+kw_0\) 更新答案。

      理解:大于 \(0\) 的边相当于这条边会加入答案贡献,那么超过 \(k\) 条一定不优;小于 \(k\) 条虽然不合法,但是一定会被 \(w_0\) 变小的方案覆盖掉。

      最终复杂度就是 \(\mathcal O(m^2\log m)\) 的。

    \(\mathscr{Code}\)

    /*+Rainybunny+*/
    
    #include <bits/stdc++.h>
    
    #define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
    #define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
    
    typedef long long LL;
    typedef std::pair<LL, int> PLI;
    typedef std::pair<int, int> PII;
    #define fi first
    #define se second
    
    const int MAXN = 3e3, MAXM = 3000;
    const LL LINF = 1ll << 60;
    int n, m, K, S, T, eu[MAXM + 5], ev[MAXM + 5], ew[MAXM + 5];
    std::vector<PII> adj[MAXN + 5];
    LL dis[MAXN + 5];
    
    inline void dijkstra(const int dlt) {
        static std::priority_queue<PLI, std::vector<PLI>, std::greater<PLI> > heap;
        rep (i, 1, n) dis[i] = LINF;
        heap.push({ dis[S] = 0, S });
        while (!heap.empty()) {
            PLI p(heap.top()); heap.pop();
            if (p.fi != dis[p.se]) continue;
            for (auto& [v, w]: adj[p.se]) {
                int nw = std::max(w - dlt, 0);
                if (dis[v] > nw + p.fi) {
                    heap.push({ dis[v] = nw + p.fi, v });
                }
            }
        }
    }
    
    int main() {
        // freopen("fee.in", "r", stdin);
        // freopen("fee.out", "w", stdout);
        std::ios::sync_with_stdio(false), std::cin.tie(0);
    
        std::cin >> n >> m >> K, S = 1, T = n;
        rep (i, 1, m) {
            std::cin >> eu[i] >> ev[i] >> ew[i];
            adj[eu[i]].emplace_back(ev[i], ew[i]);
            adj[ev[i]].emplace_back(eu[i], ew[i]);
        }
    
        dijkstra(0);
        LL ans = dis[T];
        rep (i, 1, m) {
            dijkstra(ew[i]);
            ans = std::min(ans, dis[T] + 1ll * ew[i] * K);
        }
        std::cout << ans << '\n';
        return 0;
    }
    
    
  • 相关阅读:
    浅析Vue Router中关于路由守卫的应用以及在全局导航守卫中检查元字段
    react-native 项目配置ts运行环境
    #mobx应用在rn项目中
    react-native TextInput输入框输入时关键字高亮
    react-native-亲测可用插件
    nodejs+express实现图片上传
    cordova图片上传,视频上传(上传多个图片,多个视频)
    cordova图片上传,视频上传(上传单个图片,单个视频)
    移动端如何测试(前端,cordova)
    在mac上将apk包安装到android手机上
  • 原文地址:https://www.cnblogs.com/rainybunny/p/15964390.html
Copyright © 2020-2023  润新知