• AtCoder Beginner Contest 237 E Skiing(dijkstra处理负权)


    E - Skiing

    题目大意:

    \(n\) 个点每个点有一个点权,依据点权的大小关系确定 \(m\) 条边权,求最长路。

    思路:

    关于SPFA,他死了。

    很明显是求带负权的最长路,赛后有数据毙掉SPFA,考虑如何转化边权使得可以用 dijkstra 求解。

    我们将点权看作势能,加入到最短路的求解中。

    设原边权为 \(w(u, v)\),新边权为 \(\bar{w}(u, v)=w(u, v)+h[u]-h[v]\)

    假设最短路径为 1-->2-->3-->4,

    那么新的最短路径为

    \[\begin{array}{l} \bar{w}(1,2)+\bar{w}(2,3)+\bar{w}(3,4) \\ =w(1,2)+h[1]-h[2]+w(2,3)+h[2]-h[3]+w(3,4)+h[3]-h[4] \\ =w(1,2)+w(2,3)+w(3,4)+h[1]-h[4] \end{array} \]

    可以看到,新的最短路径只与起点和终点的势能有关。

    考虑这样转化后的边权。

    记取反后的边权为 \(\tilde{w}(u, v)\)

    如果 \(h[u] > h[v]\)

    \(w(u, y) = h[u] - h[v]\)

    \(\tilde{w}(u, y) = h[v] - h[u]\)

    \(\bar{w}(u, v) = h[v] - h[u] + h[u] - h[v] = 0\)

    如果 \(h[u] < h[v]\)

    \(w(u, y) = -2(h[v] - h[u])\)

    \(\tilde{w}(u, y) = 2(h[v] - h[u])\)

    \(\bar{w}(u, v) = 2(h[v] - h[u]) + h[u] - h[v] = h[v] - h[u] > 0\)

    这样,边权加入了势能后就都是非负的,可以运用 dijstra 求最长路。

    具体的,得到的答案 \(dis[u]\) 减去势能 \(h[1] - h[u]\),再取反得到最长路,即 \(-(dis[u] - (h[1] - h[u]))\)

    Code:
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int n, m;
        cin >> n >> m;
        vector<int> h(n + 1);
        for (int i = 1; i <= n; i++) {
            cin >> h[i];
        }
        for (int i = 0; i < m; i++) {
            int u, v;
            cin >> u >> v;
            if (h[u] > h[v]) {
                addedge(u, v, 0);
                addedge(v, u, h[u] - h[v]);
            } else if (h[u] == h[v]) {
                addedge(u, v, 0);
                addedge(v, u, 0);
            } else {
                addedge(v, u, 0);
                addedge(u, v, h[v] - h[u]);
            }
        }
    
        dijkstra(n, 1);
    
        ll ans = 0;
        for (int u = 1; u <= n; u++) {
            if (dis[u] == INF)
                continue;
            ans = max(ans, -(dis[u] - (h[1] - h[u])));
        }
        cout << ans << "\n";
        return 0;
    }
    
  • 相关阅读:
    CCF-CSP的第三题们么
    STL
    信息安全-期末复习
    NLP自然语言处理
    python 处理文件
    信息安全-简易的DES加解密--3DES
    试药的常见问题
    关于试药的那些事
    Excel的单列和多列的拆分与合并
    Excel中的文本提取操作
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/15959096.html
Copyright © 2020-2023  润新知