当前位置: 首页 > news >正文

ch06 部分题目思路

D. 异地

仅需在最短路算法中,希望使用 d[u]+w 松弛 d[v] 时,把 du 替换 >= duk 的倍数的最小值即可

using ll = long long;
const int maxn = 100010;
struct edge {int v, t, k;ll w;  // 最短路bool operator<(const edge &e) const { return w > e.w; }
};
vector<edge> G[maxn];
ll d[maxn];
int n;
priority_queue<edge> q;
void dij(int s) {memset(d, 0x3f, sizeof(d));d[s] = 0;q.push({s, 0});while (!q.empty()) {edge e = q.top();int u = e.v;q.pop();if (e.w > d[u]) continue;for (int i = 0; i < G[u].size(); ++i) {int v = G[u][i].v, k = G[u][i].k, t = G[u][i].t;// 需要从 du 开始等到 k 的倍数出发ll du = (d[u] + k - 1) / k * k;if (d[v] > du + t) {d[v] = du + t;q.push({v, t, k, d[v]});}}}return;
}
int main() {// s 为单源最短路的源点int m, u, v, t, k, x, y;cin >> n >> m >> x >> y;for (int i = 0; i < m; ++i) {cin >> u >> v >> t >> k;G[u].push_back({v, t, k, 0});G[v].push_back({u, t, k, 0});}dij(x);if (d[y] == 0x3f3f3f3f3f3f3f3f) cout << -1 << endl;else cout << d[y] << endl;return 0;
}

F. 滑雪

把(幸福感 * -1)设为边权,求 1 出发能获得最大幸福感,等价于求图上的最短路长度 * -1

此时边权有负权,跑 SPFA 算法,部分样例会超时,可拿大部分分数(98分)。

继续优化时间:

  • 建边时,对所有的边(u -> v),加上 h[u] - h[v],此时边权全为非负。

  • 在新图上,路径 1(x0) -> x1 -> x2 -> x3 -> xk 的边权和就变成

    • (w1+h[1]-h[x1]) + (w2+h[x1]-h[x2]) + (w3+h[x3]-h[x2]) + ...
    • = w1 + w2 + ... + wk + h[1] - h[k]
  • 所以以 1 为起点跑 Dijkstra 算法,此时 d[u] = 1 到 u 的最短路 + h[1] - h[u]

  • 最终答案在所有 -(d[u] - h[1] + h[u]) 中,取最大值即可

#include <bits/stdc++.h>
using namespace std;using ll = long long;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 200010;
struct Edge {int v, w;
};
vector<Edge> G[maxn];
struct Node {int u;ll d;bool operator<(const Node &n) const { return d > n.d; }
};
ll d[maxn];
bool vis[maxn];void Dij(int s) {// 一定要初始化memset(d, 0x3f, sizeof(d));priority_queue<Node> pq;d[s] = 0, pq.push({s, d[s]});while (!pq.empty()) {int u = pq.top().u;pq.pop();// u 可以进入 pq 多次,只取第一次if (vis[u]) continue;vis[u] = 1;for (Edge e : G[u]) {int v = e.v, w = e.w;if (d[v] > d[u] + w) {d[v] = d[u] + w;pq.push({v, d[v]});}}}
}// ---------------- 以上为最短路模板int h[maxn];
int main() {int n, m;cin >> n >> m;for (int i = 1; i <= n; ++i) cin >> h[i];// 输入格式:a[i] b[i] x[i]for (int i = 0; i < m; ++i) {int u, v;cin >> u >> v;if (h[u] < h[v]) swap(u, v);G[u].push_back({v, 0});G[v].push_back({u, h[u] - h[v]});}Dij(1);ll res = 0;for (int i = 1; i <= n; ++i) {// if (d[i] == inf) continue; // 题目保证连通// d[i] = sumW + h[1] - h[i]ll sumW = d[i] - h[1] + h[i];res = max(res, -sumW);}cout << res << "\n";return 0;
}
http://www.lryc.cn/news/585701.html

相关文章:

  • OpenCV实现感知哈希(Perceptual Hash)算法的类cv::img_hash::PHash
  • 深入探究编程拷贝
  • 基于Java Spring Boot开发的旅游景区智能管理系统 计算机毕业设计源码32487
  • 4万亿英伟达,凭什么?
  • 【Linux应用】Ubuntu20.04 aarch64开发板一键安装ROS2(清华源)
  • PandaCoder重大产品更新-引入Jenkinsfile文件支持
  • mysql的LIMIT 用法
  • 【AI大模型】超越RAG的搜索革命!分层框架让AI像专家团队一样深度思考
  • Java教程:JavaWeb ---MySQL高级
  • 隆重介绍 Xget for Chrome:您的终极下载加速器
  • linux kernel struct regmap_config结构详解
  • 【Quest开发】快速添加可手指触摸按钮
  • 3 OneNET-调试器模拟上报数据
  • Visual Studio Code 的 settings.json 配置指南
  • HarmonyOS NEXT端云一体化开发初体验
  • 世俱杯直播数据源通过反汇编获取到
  • gradle中namespace和applicationId的区别
  • Ubuntu20.04运行openmvg和openmvs实现三维重建(未成功,仅供参考)
  • 【酶解法】小鼠脾脏单细胞悬液的制备指南
  • 云网络产品
  • 7.11文件和异常
  • linux中cmake编译项目
  • 5G标准学习笔记15 --CSI-RS测量
  • Next知识框架、SSR、SSG和ISR知识框架梳理
  • SwiGLU是什么:Swish激活函数和门控线性单元(GLU)机制的激活函数
  • 2025 年第十五届 APMCM 亚太地区大学生数学建模竞赛C题 基于Quantum Boosting的二分类模型问题
  • 实时数仓和离线数仓还分不清楚?看完就懂了
  • defer关键字
  • PHT-CAD 笔记
  • 你见过的最差的程序员是怎样的?