CF1253F Cheap Robot 题解
首先建立一个超级点
假设当前 Robot 走到了一个点
考虑枚举每一条
也就是说,从
但是问题是有
容易发现(很容易吗),若对于每一条边的最小需要电池容量都已经求出,那么考虑建图
因为有
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 300100;
vector<pair<int, int>> z[N], y[N];
struct { int u, v, w; } ed[N];
int fa[N], dis[N], dep[N], f[N][20], g[N][20], n, m, k, Q;
bool vis[N];
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void spfa(int u) {
queue<int> q;
q.push(u);
vis[u] = true;
memset(dis, 0x3f, sizeof dis);
dis[u] = 0;
while (q.size()) {
int f = q.front();
q.pop();
vis[f] = false;
for (auto &[g, w] : z[f])
if (dis[g] > dis[f] + w) {
dis[g] = dis[f] + w;
if (!vis[g]) vis[g] = true, q.push(g);
}
}
}
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1, f[u][0] = fa;
for (auto &[v, w] : y[u])
if (v != fa)
g[v][0] = w, dfs(v, u);
}
void init() {
for (int i = 1; i < 20; i++)
for (int j = 1; j <= n; j++) {
f[j][i] = f[f[j][i - 1]][i - 1];
g[j][i] = max(g[j][i - 1], g[g[j][i - 1]][i - 1]);
}
}
int lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
for (int i = 0; i < 20; i++)
if ((dep[u] - dep[v]) >> i & 1) u = f[u][i];
if (u == v) return u;
for (int i = 19; ~i; i--)
if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
return f[u][0];
}
int query(int u, int v) {
int mx = 0;
if (dep[u] < dep[v]) swap(u, v);
for (int i = 0; i < 20; i++)
if ((dep[u] - dep[v]) >> i & 1) mx = max(mx, g[u][i]), u = f[u][i];
if (u == v) return mx;
for (int i = 19; ~i; i--)
if (f[u][i] != f[v][i]) mx = max({mx, g[u][i], g[v][i]}), u = f[u][i], v = f[v][i];
return max({mx, g[u][0], g[v][0]});
}
signed main() {
cin >> n >> m >> k >> Q;
for (int i = 0; i < m; i++) {
cin >> ed[i].u >> ed[i].v >> ed[i].w;
z[ed[i].u].push_back({ed[i].v, ed[i].w});
z[ed[i].v].push_back({ed[i].u, ed[i].w});
}
for (int i = 1; i <= k; i++)
z[0].push_back({i, 0}), z[i].push_back({0, 0});
spfa(0);
for (int i = 0; i < m; i++)
ed[i].w += dis[ed[i].u] + dis[ed[i].v];
sort(ed, ed + m, [&](auto l, auto r) {
return l.w < r.w;
});
for (int i = 1; i <= n; i++)
fa[i] = i;
for (int i = 0; i < m; i++) {
int ta = find(ed[i].u), tb = find(ed[i].v), c = ed[i].w;
if (ta != tb) fa[ta] = tb, y[ed[i].u].push_back({ed[i].v, ed[i].w}), y[ed[i].v].push_back({ed[i].u, ed[i].w});
}
dfs(1, 0);
init();
while (Q--) {
int u, v;
cin >> u >> v;
cout << query(u, v) << '\n';
}
return 0;
}
本文来自博客园,作者:yhbqwq,转载请注明原文链接:https://www.cnblogs.com/yhbqwq/p/18136220,谢谢QwQ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧