CF1473E. Minimum Path 题解 分层图最短路

题目链接:https://codeforces.com/problemset/problem/1473/E

dis[u][c1][c2] 表示到达顶点 \(u\) 有无经过最短边(\(c1\) 标记)有无经过最长边(\(c2\) 标记)时的最短路。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;

int n, m;
long long dis[maxn][2][2];
bool vis[maxn][2][2];

struct Node {
    int u, c1, c2;
    long long dis;

    bool operator < (const Node &b) const {
        return dis > b.dis;
    }
};

struct Edge {
    int v, w;
};
vector<Edge> g[maxn];

void dijkstra() {
    for (int i = 1; i <= n; i++)
        for (int j = 0; j < 2; j++)
            for (int k = 0; k < 2; k++)
                dis[i][j][k] = 1ll<<60;
    dis[1][0][0] = 0;
    priority_queue<Node> que;
    que.push({1, 0, 0, 0});
    while (!que.empty()) {
        Node nd = que.top();
        que.pop();
        int u = nd.u, c1 = nd.c1, c2 = nd.c2;
        long long _dis = nd.dis;
        if (vis[u][c1][c2]) continue;
        vis[u][c1][c2] = true;
        for (auto e : g[u]) {
            int v = e.v, w = e.w;
            if (dis[v][c1][c2] > dis[u][c1][c2] + w) {
                dis[v][c1][c2] = dis[u][c1][c2] + w;
                que.push({v, c1, c2, dis[v][c1][c2]});
            }
            if (!c1) {
                if (dis[v][c1+1][c2] > dis[u][c1][c2] + 2 * w) {
                    dis[v][c1+1][c2] = dis[u][c1][c2] + 2 * w;
                    que.push({v, c1+1, c2, dis[v][c1+1][c2]});
                }
            }
            if (!c2) {
                if (dis[v][c1][c2+1] > dis[u][c1][c2]) {
                    dis[v][c1][c2+1] = dis[u][c1][c2];
                    que.push({v, c1, c2+1, dis[v][c1][c2+1]});
                }
            }
            if (!c1 && !c2) {
                if (dis[v][c1+1][c2+1] > dis[u][c1][c2] + w) {
                    dis[v][c1+1][c2+1] = dis[u][c1][c2] + w;
                    que.push({v, c1+1, c2+1, dis[v][c1][c2]});
                }
            }
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }
    dijkstra();
    for (int i = 2; i <= n; i++)
        printf("%lld ", dis[i][1][1]);
    return 0;
}

posted @ 2025-04-01 19:00  quanjun  阅读(28)  评论(0)    收藏  举报