【问题描述】

由于女交警太多,lpq与她们的联络就成了一个问题。他决定构建一个联络网以便联系。
lpq不希望网络太复杂,于是他把联络网设计成了一棵树,这样每次需要联络的时候lpq只需给任意一个女交警发短信便可以将信息传达给所有的女交警。我们可以认为女交警从接到短信到群发出去的时间为1。
在这个联络网用了一段时间后,lpq发现了一个问题:当他给某个女交警发短信时,转达到一些人需要的时间非常长,这样导致耽误了约会。而lpq又不愿意浪费短信费,他希望每次需要联络时只给一个女交警打电话。lpq十分苦恼,他决定修改联络网的一条树边(把这条树边删去,再添加一条边)。他希望使修改后的联络网满足:从给任意一个女交警发短信开始,到联络到所有女交警的最长时间尽量短
lpq找到了你帮忙,你一定要帮帮他!

【输入格式】

输入文件network.in包含若干行。
第一行包含一个整数N,表示有N个女交警。
接下来的N-1行,每行两个整数A、B,表示A与B之间有边相连。

【输出格式】

输出文件network.out只包含一行,为一个整数,表示修改后联络的最短时间。

【样例输入】

5
1 2
2 3
3 4
4 5

【样例输出】

3

【数据范围】

对于30%的数据,n≤50
对于100%数据,n≤2500

【30分】O(n4)O(n^4)树形DP

如果要删除或添加某条边,最暴力的思想是考虑直接O(n3)O(n^3)枚举,则我们只要求出这样暴力重构的新树的最长链。
对于包含某一个点的最长链,显然有如下两种情况:

我们记f[x][1]f[x][1]和f[x][0]f[x][0]分别表示自点xx向下延伸到叶节点的最长链和次长链的长度,可由xx的子节点yy转移过来,一遍DFSDFS回溯即可求出。
那么对于第二种情况就可表示为f[x][1]+f[x][0]f[x][1] + f[x][0],而第一种情况因为我们要遍历到根节点,实际也会考虑进去。

【100分】O(n2)O(n^2)树形DP

思考后我们可以发现:实际上我们枚举O(n)O(n)删除边后,新生成的两棵树的最长链可以由如下图的三种情况得到:
[1]、新生成的第一棵树的最长链(黑);
[2]、新生成的第二棵树的最长链(蓝);
[3]、将第一棵树的某一点向第二棵树的某一点添加一条边,经过这条新边所形成的新的最长链(红)。

前两种情况就是我们上述的最长链DP,第三种情况的两点实际上是可以贪心得到的,我们选取两棵树中向上和向下延伸的最长链长度的最大值最小的两个节点作为答案(这是为什么呢?首先最大值保证包含该节点能构成最长链,最小是题目要求的最优方案)。
同样,向下延伸的最长链长度可以由f[x][0]+f[x][1]f[x][0] + f[x][1]得到,向上延伸的最长链长度我们可以通过第二遍DFSDFS得到。当DFSDFS到节点yy时:yy向上延伸的最长链长度可由xx向上延伸的最长链长度与f[x][1]f[x][1]的最大值加一得到,但若yy在xx向下延伸的最长链上,则不能选取f[x][1]f[x][1],而要选取f[x][0]f[x][0]。

【代码】

#include <cstdio>
#include <iostream>
#include <cstring> using namespace std;
const int Maxn = 1 << 30;
const int N = 2505, M = 5005;int f[N][2], dep[N], lst[N], to[M], nxt[M], fr[M], lft[N], lar[N];
int Ans, n, EdAns = Maxn, tx, ty, T = 1;inline int get()
{char ch; int res = 0;while ((ch = getchar()) < '0' || ch > '9');res = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9')res = (res << 3) + (res << 1) + ch - '0';return res;
}inline void addEdge(const int &x, const int &y)
{nxt[++T] = lst[x]; lst[x] = T; to[T] = y; fr[T] = x;nxt[++T] = lst[y]; lst[y] = T; to[T] = x; fr[T] = y;
}inline void CkMax(int &x, const int &y){if (x < y) x = y;}
inline int Max(const int &x, const int &y){return x > y ? x : y;}
inline void CkMin(int &x, const int &y) {if (x > y) x = y;}inline void Dfs1(const int &x, const int &fa)
{f[x][0] = f[x][1] = -1;for (int i = lst[x], y; i; i = nxt[i]){if ((y = to[i]) == fa) continue;Dfs1(y, x); int tmp = f[y][1] + 1;if (tmp > f[x][1])f[x][0] = f[x][1], f[x][1] = tmp, lft[x] = y;else if (tmp > f[x][0]) f[x][0] = tmp;}}inline void Dfs2(const int &x, const int &fa, const int &Cast, int &st)
{int tmp = Max(Cast, f[x][1]) + 1;CkMax(Ans, tmp); CkMin(st, tmp);for (int i = lst[x], y; i; i = nxt[i]){if ((y = to[i]) == fa) continue;if (y == lft[x]) Dfs2(y, x, Max(Cast, f[x][0]) + 1, st);//lft[x]用来判断y是否在x向下延伸的最长链上 else Dfs2(y, x, tmp, st);}}int main()
{freopen("network.in", "r", stdin);freopen("network.out", "w", stdout);n = get();for (int i = 1; i < n; ++i) addEdge(get(), get());for (int i = 2; i <= T; i += 2){tx = ty = Maxn; Ans = 0;Dfs1(fr[i], to[i]); Dfs2(fr[i], to[i], -1, tx);Dfs1(to[i], fr[i]); Dfs2(to[i], fr[i], -1, ty);CkMax(Ans, tx + ty + 1);if (EdAns > Ans) EdAns = Ans;}printf("%d\n", EdAns);fclose(stdin); fclose(stdout);return 0;
}

[日常训练] 联络网相关推荐

  1. codeforces日常训练 C. Cutting Out - 二分搜索答案

    codeforces日常训练 C. Cutting Out - 二分搜索答案 题干 You are given an array s consisting of n integers. You hav ...

  2. 程序员的算法趣题Q57: 最快的联络网

    目录 1. 问题描述 2. 解题分析 2.1 学生的状态 2.2 学生状态转移 Case-T1:Do nothing, just wait Case-T2:给处于S0状态的学生打电话 Case-T3: ...

  3. 「日常训练」Common Subexpression Elimination(UVa-12219)

    今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...

  4. 「日常训练」 Mike and Fun (CFR305D2B)

    题意(CodeForces 548B) 每次对01矩阵中的一位取反,问每次操作后,单列中最长连续1的长度. 分析 非常非常简单,但是我当时训练的时候WA了四次...无力吐槽了,人间 不值得.jpg 代 ...

  5. 动规日常训练题解 难度普及+

    9.6 动规训练  题解 ----Frosty_Jackal 定义Dpmax[i][j] 表示l~r之间最大的得分,由题意得拆环为链,将1~n的枚举范围扩大到1~2*n ,外层枚举区间长,内层枚举l, ...

  6. 产品思维训练 | 百度网盘的会员制变更

    本周话题: 百度网盘更改现有的会员模式,即将推出单次付费服务. 阶段性(年/季度/月)会员与单次付费这两种模式有什么不同?如果你是用户,你选择哪种模式?为什么? 下面给大家分享几个群内同学的思考角度, ...

  7. [日常]win10解除网速限制

    我的win10网速奇慢 , 经过一番搜索 , 找到这个方法 win + r 打开输入 gpedit.msc 打开组策略编辑 , 默认情况下系统会限制20%的网速 启用这个 , 然后输入0 保存

  8. 日常 - CompletableFuture 异步网约车服务超时未关闭

    项目场景: KC 项目是和多个网约车供应商合作,通过供应商提供的 API 接口请求叫车.由于与多个供应商合作,需求同一时间可叫多个供应商,但若采取同步叫车将会导致等待时间过长,因此叫车时采用多线程异步 ...

  9. 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)

    题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ...

最新文章

  1. 1750亿参数,史上最大AI模型GPT-3上线:不仅会写文章、答题,还懂数学
  2. 如何读群晖硬盘_更新教程:群晖下直接挂载WINDOWS的NTFS格式硬盘,试验通过......
  3. Djaongo 中间件
  4. Intel Core Enhanced Core架构/微架构/流水线 (7) - 栈指针跟踪器/微熔合
  5. Google TakeOut图片下载器
  6. Map 3D 2011 在线帮助真正在线了 :)
  7. goroutine 相关知识8
  8. 2022电工杯:5G 网络环境下应急物资配送问题(优化)
  9. 实信号变成解析信号的实现方法
  10. Struts2 教程 流程
  11. 调试 STM32F429 + USB3300
  12. 记忆翻牌游戏——react算法学习
  13. 学习笔记二:关于自激振荡
  14. 挑食有理——罗敏娜集团总裁卓顺发养生之道
  15. 创建anaconda虚拟环境步骤
  16. 如何尴尬而又不失礼貌的拒绝大厂offer?
  17. GB/T35590-2017移动电源CMA检测报告,移动电源新国标检测
  18. APP开发流程注意事项有哪些
  19. 使用imagine/imagine实现制作一个图片
  20. 基于开源大模型Vicuna-13B构建私有制库问答系统

热门文章

  1. 系统部署在服务器,如何把系统部署在云服务器
  2. Butter Knife[黄油刀]配置
  3. linux下jmeter性能测试
  4. Unity3D 模型分块
  5. 【论文阅读】SyncPerf: Categorizing, Detecting, and Diagnosing Synchronization Performance Bugs
  6. 上线切换 - 如何导入在制品
  7. 教学向|ZB利用分组Dynamesh,对模型进行重建细分!
  8. 2022企业电子邮件在哪里找,企业电子邮件系统哪个安全?
  9. Python3.6+Twisted+Scrapy安装
  10. 【转载】PCB设计方法和技巧