zoukankan      html  css  js  c++  java
  • [CF1473E] Minimum Path

    [CF1473E] Minimum Path - 分层图最短路

    Description

    给定一个无向图,定义路径的权值为路径上所有边权的和减去边权的极差。求 1 到其它所有点的最短路。

    Solution

    很妙的转化:一条边权值变成 0,一条边权值加倍,求最短路

    转化后的条件加上最短的条件,就得到了转化前的条件

    于是分层图最短路即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    
    #define reset(x) memset(x, 0, sizeof x)
    #define reset3f(x) memset(x, 0x3f, sizeof x)
    namespace sp
    {
        const int N = 1e+6 + 5;
        vector<pair<int, int>> g[N];
        int n, v0 = 1, d[N], v[N];
        void make(int t1, int t2, int t3)
        {
            g[t1].push_back(make_pair(t2, t3));
        }
        void reset_graph()
        {
            for (int i = 0; i <= n; i++)
                g[i].clear();
        }
        void solve()
        {
            priority_queue<pair<int, int>> qu;
            reset3f(d);
            reset(v);
            d[v0] = 0;
            qu.push(make_pair(0, v0));
            while (qu.size())
            {
                int p = qu.top().second, r = qu.top().first;
                qu.pop();
                if (r + d[p])
                    continue;
                for (int i = 0; i < g[p].size(); i++)
                {
                    int q = g[p][i].first, w = g[p][i].second;
                    if (d[q] > d[p] + w)
                    {
                        d[q] = d[p] + w;
                        qu.push(make_pair(-d[q], q));
                    }
                }
            }
        }
    } // namespace sp
    
    int n, m, s, t1, t2, t3;
    
    signed main()
    {
        cin >> n >> m;
        s = 1;
        int ORIGIND = 0;
        int DOUBLED = n * 2;
        int IGNORED = n;
        int DOUIGND = n * 3;
    
        for (int i = 1; i <= n; i++)
        {
            sp::make(i, i + n, 0);
            sp::make(i + 2 * n, i + 3 * n, 0);
            sp::make(i, i + 3 * n, 0);
        }
    
        for (int i = 1; i <= m; i++)
        {
            cin >> t1 >> t2 >> t3;
    
            sp::make(t1 + ORIGIND, t2 + ORIGIND, t3);
            sp::make(t1 + DOUBLED, t2 + DOUBLED, t3);
            sp::make(t1 + IGNORED, t2 + IGNORED, t3);
            sp::make(t1 + DOUIGND, t2 + DOUIGND, t3);
    
            sp::make(t1 + ORIGIND, t2 + DOUBLED, t3 * 2);
            sp::make(t1 + IGNORED, t2 + DOUIGND, t3 * 2);
    
            sp::make(t1 + ORIGIND, t2 + IGNORED, 0);
            sp::make(t1 + DOUBLED, t2 + DOUIGND, 0);
    
            swap(t1, t2);
    
            sp::make(t1 + ORIGIND, t2 + ORIGIND, t3);
            sp::make(t1 + DOUBLED, t2 + DOUBLED, t3);
            sp::make(t1 + IGNORED, t2 + IGNORED, t3);
            sp::make(t1 + DOUIGND, t2 + DOUIGND, t3);
    
            sp::make(t1 + ORIGIND, t2 + DOUBLED, t3 * 2);
            sp::make(t1 + IGNORED, t2 + DOUIGND, t3 * 2);
    
            sp::make(t1 + ORIGIND, t2 + IGNORED, 0);
            sp::make(t1 + DOUBLED, t2 + DOUIGND, 0);
        }
    
        sp::solve();
    
        for (int i = 2; i <= n; i++)
        {
            cout << sp::d[i + DOUIGND] << " ";
        }
    }
    
    
  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/mollnn/p/14340725.html
Copyright © 2011-2022 走看看