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;
}
浙公网安备 33010602011771号