Codeforces Round 888 (Div. 3)G. Vlad and the Mountains(数据结构,图论)

题目链接:https://codeforces.com/contest/1851/problem/G

 

大致题意:

 

给出n个点m条边的无向图,每个点有点权h【i】。从点 i 到 点 j会消耗 h【j】 - h【i】 的能量,如果小于0,那么就是恢复对应绝对值的能量。

 

进行q次询问,每次询问包含起点s,终点t,能量e,能量在移动过程 中不能小于0,问是否能从s到t;

 

解题思路:

 

转化问题(结合律,然后抵消中间项),相当于不经过h【s】 + e的点,s和e是否连通;

 

然后无向图连通问题可以用并查集来维护;

 

考虑离线做法,我们对能量进行排序(从小到大);

 

然后依次建边合并,查询即可;

 

时间复杂度:O(nlogn);

 

代码:

 

#include<bits/stdc++.h> const int N = 2e5 + 5; int p[N], h[N]; int FIND(int x) { return p[x] = (x == p[x] ? x : FIND(p[x])); } struct I { int u, v, h, op, id; }; bool my_cmp(I a, I b) { if (a.h != b.h)return a.h < b.h; if (a.op != b.op)return a.op < b.op; return a.id < b.id; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int T; std::cin >> T; while (T--) { int n, m; std::cin >> n >> m; for (int i = 1; i <= n; ++i)std::cin >> h[i], p[i] = i; std::vector<I> U; for (int i = 1; i <= m; ++i) { int a, b; std::cin >> a >> b; U.push_back({a, b, std::max(h[a], h[b]), 0, N + i}); } int q; std::cin >> q; for (int i = 1; i <= q; ++i) { int a, b, x; std::cin >> a >> b >> x; U.push_back({a, b, h[a] + x, 1, i}); } std::sort(U.begin(), U.end(), my_cmp); /*for (int i = 0; i < U.size(); ++i) std::cout << U[i].u << " " << U[i].v << " " << U[i].h << " " << U[i].op << " " << U[i].id << "\n";*/ std::vector<int> ans(q + 1, 0); for (int i = 0; i < U.size(); ++i) { if (U[i].op)ans[U[i].id] = (FIND(U[i].u) == FIND(U[i].v)); else p[FIND(U[i].u)] = FIND(U[i].v); } for (int i = 1; i <= q; ++i)std::cout << (ans[i] ? "YES\n" : "NO\n"); std::cout << "\n"; } return 0; }

不是很难的图论+数据结构的题目,但是码量还是有点大的:)


__EOF__

本文作者XiCen
本文链接https://www.cnblogs.com/ACMER-XiCen/p/17660109.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   XiCen  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示