codeforces1473E Minimum Path(spfa变形)

传送门
如果只求第 1 1 1个点分别到第 i i i个点的最小值,那么直接跑个 d i j dij dij,但是本题加了路径上分别要减去最大值和加上最小值,那么考虑 d [ i ] [ 0 / 1 ] [ 0 / 1 ] d[i][0/1][0/1] d[i][0/1][0/1]分别表示为从第 1 1 1个点到第 i i i个点没减去最大值/已经减去最大值和没减去最小值/已经减去最小值的最小路径,那么最后答案必然是各个 d [ i ] [ 1 ] [ 1 ] d[i][1][1] d[i][1][1],最后分析一波
d [ v ] [ 0 ] [ 0 ] = m i n ( d [ u ] [ 0 ] [ 0 ] + w , d [ v ] [ 0 ] [ 0 ] ) d [ v ] [ 1 ] [ 0 ] = m i n ( d [ u ] [ 0 ] [ 0 ] , d [ v ] [ 1 ] [ 0 ] ) d [ v ] [ 1 ] [ 0 ] = m i n ( d [ u ] [ 1 ] [ 0 ] + w , d [ v ] [ 1 ] [ 0 ] d [ v ] [ 0 ] [ 1 ] = m i n ( d [ u ] [ 0 ] [ 0 ] + 2 ∗ w , d [ v ] [ 0 ] [ 1 ] ) d [ v ] [ 0 ] [ 1 ] = m i n ( d [ u ] [ 0 ] [ 1 ] + w , d [ v ] [ 0 ] [ 1 ] ) d [ v ] [ 1 ] [ 1 ] = m i n ( d [ u ] [ 0 ] [ 0 ] + w , d [ v ] [ 1 ] [ 1 ] ) d [ v ] [ 1 ] [ 1 ] = m i n ( d [ u ] [ 1 ] [ 0 ] + 2 ∗ w , d [ v ] [ 1 ] [ 1 ] ) d [ v ] [ 1 ] [ 1 ] = m i n ( d [ u ] [ 0 ] [ 1 ] , d [ 1 ] [ 1 ] [ 1 ] ) d [ v ] [ 1 ] [ 1 ] = m i n ( d [ u ] [ 1 ] [ 1 ] + w , d [ v ] [ 1 ] [ 1 ] ) d[v][0][0]=min(d[u][0][0]+w,d[v][0][0])\\ d[v][1][0]=min(d[u][0][0],d[v][1][0])\\ d[v][1][0]=min(d[u][1][0]+w,d[v][1][0]\\ d[v][0][1]=min(d[u][0][0]+2*w,d[v][0][1])\\ d[v][0][1]=min(d[u][0][1]+w,d[v][0][1])\\ d[v][1][1]=min(d[u][0][0]+w,d[v][1][1])\\ d[v][1][1]=min(d[u][1][0]+2*w,d[v][1][1])\\ d[v][1][1]=min(d[u][0][1],d[1][1][1])\\ d[v][1][1]=min(d[u][1][1]+w,d[v][1][1]) d[v][0][0]=min(d[u][0][0]+w,d[v][0][0])d[v][1][0]=min(d[u][0][0],d[v][1][0])d[v][1][0]=min(d[u][1][0]+w,d[v][1][0]d[v][0][1]=min(d[u][0][0]+2w,d[v][0][1])d[v][0][1]=min(d[u][0][1]+w,d[v][0][1])d[v][1][1]=min(d[u][0][0]+w,d[v][1][1])d[v][1][1]=min(d[u][1][0]+2w,d[v][1][1])d[v][1][1]=min(d[u][0][1],d[1][1][1])d[v][1][1]=min(d[u][1][1]+w,d[v][1][1])
然后就是不断地跑spfa更新即可(参考官方题解)

准备改改代码规范了,该空格就得空格呢,毕竟代码是给别人看的

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, m, u, v, w;
long long d[N][2][2];
vector<pair<int, int>> g[N];
int main()
{
    
    
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
    
    
        cin >> u >> v >> w;
        u--; v--;
        g[u].emplace_back(v, w);
        g[v].emplace_back(u, w);
    }
    for (int i = 0; i < n; i++) {
    
    
        for(int j = 0; j < 2; j++) {
    
    
            for(int k = 0; k < 2; k++) {
    
    
                d[i][j][k] = (long long)1e18;
            }
        }
    }
    d[0][0][0] = 0;
    set<pair<long long, array<int, 3>>> q;
    q.insert({
    
    0, {
    
    0, 0, 0}});
    while (!q.empty()) {
    
    
        auto [u, mx, mn] = q.begin()->second;
        q.erase(q.begin());
        for (auto [v, w] : g[u]) {
    
    
            for (int i = 0; i <= 1 - mx; i++) {
    
    
                for (int j = 0; j <= 1 - mn; j++) {
    
    
                    if (d[v][i | mx][j | mn] > d[u][mx][mn] + (1 - i + j) * w) {
    
    
                        auto it = q.find({
    
    d[v][i | mx][j | mn], {
    
    v, i | mx, j | mn}});
                        if (it != q.end()) {
    
    
                            q.erase(it);
                        }
                        d[v][i | mx][j | mn] = d[u][mx][mn] + (1 - i + j) * w;
                        q.insert({
    
    d[v][i | mx][j | mn], {
    
    v, i | mx, j | mn}});
                    }
                }
            }
        }
    }
    for (int i = 1; i < n; i++) {
    
    
        cout << d[i][1][1] << " ";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/112733814