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

题解:qoj7938 Graph Race

简单题。

题意:给出一张图,边权为 \(1\),每个点有属性 \(a,b\),定义一个点 \(u\) 的权值 \(f(u)\)\(\max _{u\not=v}a_v-b_v\operatorname{dis}(u,v)\),按从小到大的顺序输出与 \(1\) 相连的的点的 \(f\) 值。

做法:

首先观察到只需要输出与 \(1\) 相连的而不是任一点,说明这是有意义的。我们注意到,与 \(1\) 相连的点 \(u\),与其他 \(v\) 的距离 \(\operatorname{dis}(u,v)\)\(\operatorname{dis}(1,v)\) 相差不会超过 \(1\),所以可以直接讨论三者的贡献。

首先对于 \(\operatorname{dis}(1,v)+1\),因为这个是最差的可能,直接全部更新就可以了。

然后对于 \(\operatorname{dis}(1,v) - 1\)\(\operatorname{dis}(1,v)\),前者等于,我令 \(\operatorname{dis}(1,x)+1=\operatorname{dis}(1,y)\) 的这些边在新图上连一条 \(x\rightarrow y\) 的有向边,然后只能走这些有向边到达;后者等于我可以走一条 \(\operatorname{dis}(1,x)=\operatorname{dis}(1,y)\) 的边。

第一种边很好连,关键在于第二种我只能走一条,只能走一条这种限制很分层图,直接拆开就可以了。

记得要求 \(u\not=v\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 6e5 + 5;
int n, m, a[maxn], b[maxn], ans[maxn];
vector<int> e[maxn], g[maxn];
int dis[maxn];
void bfs(int s) {memset(dis, 0x3f, sizeof(dis));dis[s] = 0;queue<int> q; q.push(s);while(!q.empty()) {int u = q.front(); q.pop();for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if(dis[v] > dis[u] + 1) {dis[v] = dis[u] + 1;q.push(v);}}}
}
int vis[maxn], res[maxn];
struct node {int val, p;friend bool operator<(node x, node y) {return (x.val < y.val ? 1 : 0);}node() {val = -9e18, p = 0;}node(int V, int P) {val = V, p = P;}
} mx, smx;void dfs(int u) {if(vis[u])return ;vis[u] = 1;res[u] = a[u] - b[u] * dis[u];for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];dfs(v);ans[u] = max(ans[u], res[v]);}res[u] = max(res[u], ans[u]);
//	cout << u << " " << ans[u] << " " << res[u] << endl;
}
signed main() {cin >> n >> m;for (int i = 1; i <= n; i++)cin >> a[i] >> b[i];for (int i = 1; i <= m; i++) {int x, y; cin >> x >> y;e[x].push_back(y);e[y].push_back(x);}bfs(1);memset(ans, -0x3f, sizeof(ans));for (int i = 1; i <= n; i++) {node t = node{a[i] - (dis[i] + 1) * b[i], i};if(smx < t)smx = t;if(mx < smx)swap(smx, mx);}
//	cout << mx.val << " " << mx.p << endl;for (int i = 1; i <= n; i++) {for (int j = 0; j < e[i].size(); j++) {int k = e[i][j];if(dis[i] + 1 == dis[k])g[i].push_back(k), g[i + n].push_back(n + k);else if(dis[i] == dis[k])g[i].push_back(k + n);}}for (int i = 1; i <= n; i++)dis[i + n] = dis[i], dis[i] = max(dis[i] - 1, 0ll),a[i + n] = a[i], b[i + n] = b[i];for (int i = 1; i <= 2 * n; i++)dfs(i);sort(e[1].begin(), e[1].end());for (int i = 0; i < e[1].size(); i++) {if(e[1][i] == mx.p)cout << max(smx.val, ans[e[1][i]]) << endl;elsecout << max(mx.val, ans[e[1][i]]) << endl;}return 0;
}
/*
3 3
1235 123
2152 242
324 31
1 2
2 3
3 1
*/
http://www.rkmt.cn/news/23763.html

相关文章:

  • java中的初等函数
  • 【机器人】SG-Nav 分层思维链H-CoT | 在线分层3D场景图 | 目标导航 - 教程
  • 学习逆向的背景知识(自用)
  • 傅里叶变换及DCT点滴
  • 【未完待续】MkDocs 部署安装教程
  • 傅里叶变换点滴
  • How to Practice English Daily for 30 mins
  • [buuctf]jarvisoj_level3_x64
  • SpringBoot系列十三:SpringBoot面试常见问题
  • 2025 夹丝玻璃源头厂家最新推荐排行榜:解析防火 / 艺术 / 酒店等多场景厂商优势,助力精准选型
  • 2025 中空板源头厂家最新推荐排行榜揭晓:覆盖全产业链,老牌与新锐共筑品质标杆
  • 2025 年最新推荐排水沟厂家排行榜:聚焦树脂 / 线性 / 树脂混凝土 / 成品 / U 型排水沟优质企业
  • 今日学习笔记
  • 5.vtk学习——点云显示进阶
  • [LangChain] 03. 缓存
  • C语言编程之旅:从入门到实战
  • docling
  • Selenium元素定位总失败?这8种定位策略你必须掌握
  • 2025 年钢闸门源头厂家最新推荐口碑排行榜:聚焦防腐技术与密封性能,助力水利工程采购精准选型固定卷扬/四川卷扬/螺杆/螺杆式启闭机厂家推荐
  • 【Azure Developer】使用Azure Developer CLI (azd)部署项目时候遇见无法登录中国区Azure的报错
  • 2025 年清污机源头厂家最新推荐榜单:聚焦耐腐蚀与智能清污实力,权威筛选优质品牌供采购参考回转式/回转式格栅/不锈钢/四川清污机厂家推荐
  • Intellij IDEA里的各种快捷键
  • 浅谈 Tarjan 算法
  • QOJ #14426. Grid Problem 题解
  • 2025 10 18
  • 【Linux】备份
  • 2025年国内木饰面板品牌Top10权威排名及选购指南
  • 2025年市面上工程石材品牌与供应商深度解析:四川汇才石业领跑优质选择
  • 2025年市面上工程石材品牌、产品与工厂终极指南:聚焦四川汇才石业有限公司
  • 鸡兔同笼问题