Live2D

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;
}

posted @ 2022-03-04 15:01  Rainybunny  阅读(70)  评论(1编辑  收藏  举报