从[SDOI2011]消防 到[NOIP2007]树网的核

这篇具有很好参考价值的文章主要介绍了从[SDOI2011]消防 到[NOIP2007]树网的核。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有关消防一题中最优解一定在直径上的证明
P2491 [SDOI2011] 消防
P1099 [NOIP2007 提高组] 树网的核

题目描述

在一颗 \(n\) 个节点的无根树中,找到一条不超过 \(s\) 的路径,使得图中所有点到此路径距离的最大值最小,图中边权非负

分析

若想将此题转化到树网的核,需要证明对于任意一条不在直径上的路径,都能在直径上找到更优解
首先理解一个显然的结论:路径越长,结果越优

证明

以下过程中所用符号及其含义:

  • \(f(i)\) 表示从 \(i\) 出发不经过直径上的边所能到达的最长距离
  • \((u, v)\) 为树的直径, \(L\) 为直径长度
  • \((A, B)\) 为所取不在直径上的路径
  • \(d(i, j)\)\(i\)\(j\) 间的路径长

Part 1 : 所选路径与直径有交集

从[SDOI2011]消防 到[NOIP2007]树网的核
根据直径的最长性,很容易得到如下性质:

  1. 对于 \((A, C)\) 路径上的每一点\(i\), 都有\(f(i) \leq d(u, C)\)

如果大于,那么 $ f(i) + d(i, v) > L$, 与直径的最长性矛盾

  1. 对于\((D, B)\) 路径上的每一点 \(i\), 都有\(f(i) \leq d(D, v)\)

通过观察发现,只需截取 \((C, D)\) 就能满足1,2两条性质
由此我们可以将 \((A, C)\)\((D, B)\) 称作是多余的,完全可以将\(AC, DB\) 的长度转化到直径上获得更优解


第一部分证毕。

Part 2 : 所选路径与直径无交集

从[SDOI2011]消防 到[NOIP2007]树网的核

\(x \leq y\)\(y \geq \dfrac{L} {2}\)

\(val1\) 为图中所有点到 \(AB\) 的最大距离,则一定有

$$val1 = y + z $$

考虑用反证法证明:假设存在点 \(C\),使得 \(C\)\(AB\) 的距离大于 \(val1\)

其中 \(C\)\(AB\) 距离的最小值 $$d = val1 + 1$$
为了保证不重不漏,我们也把 \(C\)\(AB\) 的路径划分为经过直径不经过直径两类

case 1:

从[SDOI2011]消防 到[NOIP2007]树网的核
$ d + z + y > L $ 矛盾

case 2:

从[SDOI2011]消防 到[NOIP2007]树网的核
\((d - w - z) + (x + w) = x + y + 1 > L\) 矛盾

因此 $ val1 = y + z $ 得证。

构造更优解

从[SDOI2011]消防 到[NOIP2007]树网的核
考虑在原图中只取点 \(O\) 作为所选路径
根据定义

\[val2 = max(x, y, f(O)) = y \]

$f(O) \leq \dfrac{L}{2} $

整理一下

\[va1 = y + z, val2 = y \]
\[val2 \leq val1 \]

第二部分证毕。
由于 \(z\) 可以取到0, 一种更严谨的说法是:对于任意一条与直径不相交的路径都不能在直径上构造出次优解

文章来源地址https://www.toymoban.com/news/detail-745972.html

AC代码

#include<bits/stdc++.h>
#define ll long long

using namespace std;
const ll N = 5e5 + 5;

int n, vis[N], a[N];
ll s, d[N], sum[N];

vector<pair<int, ll> > H[N];
pair<int, ll> pre[N];

int bfs(int source) {
	memset(d, -1, sizeof d);
	queue<int> q;
	q.push(source);
	d[source] = 0;
	while(!q.empty()) {
		int x = q.front();
		q.pop();
		for(auto [y, z] : H[x]) {
			if(d[y] == -1) {
				d[y] = d[x] + z;
				pre[y] = {x, z};
				q.push(y);
			}
		}
	}
	int ret = source;
	for(int i = 1; i <= n; ++ i) {
		if(d[ret] < d[i]) ret = i;
	}
	return ret;
}

void dfs(int x) {
	vis[x] = 1, d[x] = 0;
	for(auto [y, z] : H[x]) {
		if(vis[y]) continue;
		dfs(y);
		d[x] = max(d[x], d[y] + z);
	} 
}

int main() {
	ios :: sync_with_stdio(0);
	cin.tie(nullptr);
	cin >> n >> s;
	for(int i = 1, x, y, z; i < n; ++ i) {
		cin >> x >> y >> z;
		H[x].push_back({y, z});
		H[y].push_back({x, z});
	}
	int u = bfs(1);
	int v = bfs(u);
	int p = v, idx; ll maxd = -2e9, ans = 2e9;
	while(p != u) {
		a[++ idx] = p;
		p = pre[p].first;
	}
	a[++ idx] = u;
	for(int i = 1; i <= idx; ++ i) vis[a[i]] = 1;
	for(int i = 1; i <= idx; ++ i) {
		dfs(a[i]);
		sum[i] = sum[i - 1] + pre[a[i - 1]].second;
		maxd = max(maxd, d[a[i]]);
	}
	for(int i = 1, j = 1; i <= idx; ++ i) {
		while(sum[j + 1] - sum[i] <= s && j < idx) ++ j;
		ans = min(ans, max({maxd, sum[i], sum[idx] - sum[j]}));
	}
	cout << ans;
	return 0;
}

到了这里,关于从[SDOI2011]消防 到[NOIP2007]树网的核的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • #P0998. [NOIP2007普及组] 守望者的逃离

    恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。 守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。 为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去。到那时,岛上的所有人都会遇难。 守望者的跑步

    2024年02月14日
    浏览(20)
  • 【洛谷 P1097】[NOIP2007 提高组] 统计数字 题解(映射)

    注意 :数据可能存在加强。 某次科研调查时得到了 n n n 个自然数,每个数均不超过 1.5 × 1 0 9 1.5 times 10^9 1.5 × 1 0 9 。已知不相同的数不超过 1 0 4 10^4 1 0 4 个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。 共 n + 1 n+1 n + 1 行。 第一

    2024年02月09日
    浏览(37)
  • 洛谷 P3304 [SDOI2013] 直径 题解

    题目链接 第一部分好说,求直径,dfs或者DP都可以。 第二部分,有一个定理,就是所有直径中点重叠。 那么有两种情况 一种是中点在一个节点上,那么显然这个点是每条直径的终点,也就是说直径的一半相等。从这个点出发dfs,找出所有最远点。如果只有两条,输出depth之

    2024年02月14日
    浏览(27)
  • P1972 [SDOI2009] HH的项链

    HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。 有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝

    2023年04月12日
    浏览(19)
  • 支持向量机上的核函数对比

    ​ ​

    2023年04月24日
    浏览(17)
  • Linux下多核CPU指定程序运行的核

    查看CPU核心数量:lscpu 1.4.1 通过运行时的参数设置 1.4.2 通过代码设置 查看程序的PID 查看程序可运行的核 得出该程序可以在0-3 4个核上运行。 假设我们要使程序运行在第2个核上: 查看程序的PID 查看程序可运行的CPU核 得出设置成功,已将程序绑定在CPU的第2个核上。

    2024年02月21日
    浏览(28)
  • 利用图和侧信息的核概率矩阵

    文章信息 本周阅读的论文是一篇2012年发表在《Proceedings of the 2012 SIAM International Conference on Data Mining》上关于概率矩阵分解的文章,题目为《Kernelized Probabilistic Matrix Factorization Exploiting Graphs and Side Information》。 摘要 我们提出了一种新的矩阵补全算法——核化概率矩阵分解(

    2024年04月27日
    浏览(23)
  • C语言刷题中遇到的一些很看重数学逻辑的题目(代码很简单,但是逻辑确实异曲同工)

    这一题的关键就是flat1和flat2两个变量的设立 flat1判断整个序列是否升序,比较相邻两个数,如果前者小于后者,则将flat1赋值为1 flat2判断整个序列是否升序,比较相邻两个数,如果前者大于后者,则将flat1赋值为1 然而整个序列有序的条件就是相邻的两个数一直是前者大于后

    2024年02月13日
    浏览(78)
  • 英二阅读单词【2011 t1】

    T1 危机当前,留住外部董事 apparently        显然地 attracting        吸引 compensation        薪酬 unremarked        未被注意的 take up        占用 presumably        可能 proposal        提议 weathered        平安地渡过 simply        仅仅 proxy        代理 departing        离开

    2024年02月09日
    浏览(49)
  • [COCI2010-2011#6]STEP

    目录 1.题目: 题目描述 输入格式 输出格式 2.思路 1.ans数组的维护 2.L and R 的维护 3.ne数组与pr数组的维护 4.len数组:  3.代码: 1.有注释版: 2.copy版: 给定一个长度为N的字符序列  ,初始时序列中全部都是字符L。 有 q次修改,每次给定一个 x,若为L,则将 修改成R,否则将

    2024年02月15日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包