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

P10838 『FLA - I』庭中有奇树

前言

本题解较为基础,推导如何得出二分解题思路。

题目大意

给出无根带权树,双方采取最佳策略,求节点S->T的最短路。

有两种操作:

  • 我方至多可以使用一次传送,花费k元从a传送到b(ab不能相邻)。
  • 敌方至多可以把m条道路的传送消耗设置为1e9元(单向设置,如设置a->b消耗不影响b->a)。

思路

显然的,答案可以分两种情况。

不使用传送

对方的操作不用看,答案直接S->T的最短路。

使用传送

设传送起点为u,传送终点为v。总体流程为S->u然后传送到v然后v->T。

别忘了此处u,v不能相邻。

d i s S [ i ] disS[i] disS[i]为i距起点距离, d i s T [ i ] disT[i] disT[i]为i距终点距离。答案即 d i s S [ u ] + k + d i s T [ v ] disS[u] + k + disT[v] disS[u]+k+disT[v]

通过 d f s dfs dfs预处理,我们可以在 O ( n ) O(n) O(n)得出 d i s S disS disS d i s T disT disT

使用传送的情况下,还可以再细分出两种答案。

通过对手限制的道路

消耗都是 1 e 9 1e9 1e9,所以传送越早越好。答案就是 1 e 9 1e9 1e9

如果S和T相邻的话,因为边权 < = 1 e 9 <=1e9 <=1e9,最后答案取min不会造成问题。

不通过对手限制的道路

不妨先试举几个m。

如果对方的m为0,那么答案就是最小的 ( d i s S [ u ] + d i s T [ v ] ) (disS[u] + disT[v]) (disS[u]+disT[v])然后+k。

如果对方的m为1,那么答案就是第二小的 ( d i s S [ u ] + d i s T [ v ] ) (disS[u] + disT[v]) (disS[u]+disT[v])然后+k。

朴素的想法是,暴力求出所有u,v的可能组合,其中的第m+1小 ( d i s S [ u ] + d i s T [ v ] ) + k (disS[u] + disT[v])+k (disS[u]+disT[v])+k就是答案。但是复杂度到达 n 2 n^2 n2,会tle。

直接寻找第k小显然超时。我们可以反向思考另一个问题:给出一个数字x,x在是第几小?如果能在 O ( n l o g n ) O(nlog\ n) O(nlog n)的级别以内解决这个新问题,我们只需要再套上 O ( l o g v ) O(log\ v) O(log v)二分即可获得答案。

此处反向思考是经典的第k小问题。给出例题

如何解决新问题?

我们枚举u,即固定了 d i s [ u ] dis[u] dis[u],只需要获取所有满足 d i s S [ u ] + d i s T [ v ] < = x disS[u] + disT[v] <= x disS[u]+disT[v]<=x d i s T [ v ] < = x − d i s S [ u ] disT[v] <= x - disS[u] disT[v]<=xdisS[u]

我们可以提前维护一个升序的 d i s T disT disT,再进行一次二分即可获得答案。总复杂度是 O ( n l o g n ) O(nlog\ n) O(nlog n)

此处需注意u,v不能相邻。在得到答案后,

还需枚举u的邻边y,如果 d i s S [ u ] + d i s T [ y ] < = x disS[u] + disT[y] <= x disS[u]+disT[y]<=x答案需减一。

以及考虑 d i s S [ u ] + d i s T [ u ] < = x disS[u] + disT[u] <= x disS[u]+disT[u]<=x

总结

现在我们有三部分答案

  1. 不使用传送,即 d i s T [ S ] disT[S] disT[S]
  2. 使用传送,并通过对手设置路段,即1e9
  3. 使用传送,并不通过对手设置路段,即二分出的x

三者最小即为答案。

代码如下

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
const ll N = 1e5 + 5;
int n, m, k, S, T;
vector<pll> e[N];
ll disS[N], disT[N]; //距起点和终点的距离
ll tmp[N];           //维护升序的disT用来二分
void dfs(int u, int fa, ll *dis) {for (auto &[v, w] : e[u]) {if (v == fa) continue;dis[v] = dis[u] + w;dfs(v, u, dis);}
}
bool check(ll x) {ll sum = 0;for (int u = 1; u <= n; u++) {sum += upper_bound(tmp + 1, tmp + 1 + n, x - disS[u]) - tmp - 1;for (auto &[v, w] : e[u]) { //邻边if (disS[u] + disT[v] <= x) sum--;}if (disS[u] + disT[u] <= x) sum--; //自身}return sum > m;
}
void solve() {cin >> n >> m >> k >> S >> T;for (int i = 1; i < n; i++) {int u, v, w;cin >> u >> v >> w;e[u].push_back({v, w});e[v].push_back({u, w});}dfs(S, 0, disS);dfs(T, 0, disT);for (int i = 1; i <= n; i++) tmp[i] = disT[i];sort(tmp + 1, tmp + 1 + n);ll l = 0, r = 1e18;while (l <= r) {ll mid = l + (r - l) / 2;if (check(mid)) {r = mid - 1;} else {l = mid + 1;}}cout << min({l + k, (ll)1e9, disT[S]}) << endl;
}int main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);solve();return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 人工智能时代,程序员如何保持核心竞争力?
  • “艺启创作 智绘未来”AI漫画创意大赛,燃动国漫新纪元!
  • 我的256天 创作纪念日
  • 【动态规划-最大子段和】力扣1191. K 次串联后最大子数组之和
  • 分享一个基于Node.js和Vue的农产品销售与交流平台(源码、调试、LW、开题、PPT)
  • XAI在教育领域的应用:偏见与公平
  • 【C++/STL】map和set的封装(红黑树)
  • 常见锁策略
  • anaconda下载库的方法
  • JAVA 继承和多态
  • AI 时代,Java 程序员不可不知的两个开发框架
  • 二分查找法
  • 2024年,5款高效的文献翻译工具清单。
  • C语言从头学42——预处理指令(一)
  • 【熊猫派对】
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • github从入门到放弃(1)
  • iOS 颜色设置看我就够了
  • Java 23种设计模式 之单例模式 7种实现方式
  • JavaWeb(学习笔记二)
  • php ci框架整合银盛支付
  • python3 使用 asyncio 代替线程
  • Theano - 导数
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • uva 10370 Above Average
  • vue-router 实现分析
  • Wamp集成环境 添加PHP的新版本
  • zookeeper系列(七)实战分布式命名服务
  • 笨办法学C 练习34:动态数组
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 前端技术周刊 2019-01-14:客户端存储
  • 嵌入式文件系统
  • 深度解析利用ES6进行Promise封装总结
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 携程小程序初体验
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • ionic异常记录
  • ​人工智能书单(数学基础篇)
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (1)(1.9) MSP (version 4.2)
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (多级缓存)缓存同步
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (计算机网络)物理层
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (算法)N皇后问题
  • (一)UDP基本编程步骤
  • (转)jdk与jre的区别
  • (转)树状数组
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统