【CodeForces 1473E】Minimum Path
链接:
题目大意:
给定一张
对于一条点
求点
思路:
这种路径长度中涉及最大最小,没法直接转移,考虑将题目变形。题目求
接下来实现加减操作可以建立分层图,每层都是正常连边,第一层到第二层连边权为
但这么做忽略了先加后减的情况,不妨再建一层,第一层到本层连边权为
代码:
const int N = 1e6 + 10; inline ll Read() { ll x = 0, f = 1; char c = getchar(); while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') f = -f, c = getchar(); while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * f; } int n, m, T; struct edge { int to, nxt; ll val; }e[N * 3 << 1]; int head[N], tot; void add (int u, int v, ll w) { e[++tot] = (edge) { v, head[u], w }, head[u] = tot; } struct node { int val; ll key; bool operator < (const node &a) const { return key > a.key; } }; priority_queue <node> q; ll dis[N]; bool vis[N]; void dij () { memset (dis, 127 / 3, sizeof dis); dis[1] = 0; q.push((node){ 1, 0 }); while (!q.empty()){ int u = q.top().val; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] > dis[u] + e[i].val) { dis[v] = dis[u] + e[i].val; q.push((node) { v, dis[v] }); } } } } int main() { // freopen(".in", "r", stdin); // freopen(".out", "w", stdout); n = Read(), m = Read(); for (int i = 1; i <= m; i++) { int u = Read(), v = Read(); ll w = Read(); add (u, v, w), add(v, u, w); add (u + n, v + n, w), add(v + n, u + n, w); add (u + 2 * n, v + 2 * n, w), add (v + 2 * n, u + 2 * n, w); add (u + 3 * n, v + 3 * n, w), add (v + 3 * n, u + 3 * n, w); add (u, v + n, 2 * w), add (v, u + n, 2 * w); add (u + n, v + 3 * n, 0), add(v + n, u + 3 * n, 0); add (u, v + 2 * n, 0), add (v, u + 2 * n, 0); add (u + 2 * n, v + 3 * n, 2 * w), add (v + 2 * n, u + 3 * n, 2 * w); } dij(); for (int i = 2; i <= n; i++) printf ("%lld ", min(dis[i], dis[i + 3 * n])); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步