CF14D Two Paths题解

题目链接

传送门

题意简述

给定一棵树,找出两条不经过相同点的最长路径,使得他们的长度乘积最大。

题目分析

首先,如果在一棵树上,两条路径没有共同的点,那么这两条路径对应的两个深度更小的端点之间一定有唯一一条路径,我们只需要删掉这条路径上任意一条边,就可以分离这两个路径。

看到两秒的时间限制和 \(n \le 200\) 的数据范围,我们可以想到暴力删除每一条边,在分成的两颗子树中找到直径即可。

关于如何找到直径,有两种方法,请参考oi_wiki中相关内容

此外,在删边找直径时,为了方便,我们可以直接将删掉的边 \(e\) 的两个端点 \(u\) 和 \(v\) 授予子孙关系,这样在 dfs 的时候就不会遍历到另一棵树上了。

代码示例

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define max_n 300
//以下为读入输出优化模板
void read(int &p)
{
p = 0;
int k = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
{
k = -1;
}
c = getchar();
}
while (c >= '0' && c <= '9')
{
p = p * 10 + c - '0';
c = getchar();
}
p *= k;
return;
}
void write_(int x)
{
if (x < 0)
{
putchar('-');
x = -x;
}
if (x > 9)
{
write_(x / 10);
}
putchar(x % 10 + '0');
}
void writesp(int x)
{
write_(x);
putchar(' ');
}
void writeln(int x)
{
write_(x);
putchar('\n');
}
//以上为读入输出优化模板
//需要开两个记录边的vector,e 在删边时使用,edge 在 dfs 的时候使用
vector<pair<int,int>> e;
vector<int> edge[max_n];
int n;
int dis1[max_n],dis2[max_n];//求树的直径需要用到的辅助数组,dis1[i]为从i开始最长的边,dis2[i]为从i开始第二长的边
int max_d = 0;//记录树的直径
void dfs(int u,int fa)
{
dis1[u] = dis2[u] = 0;//初值都为0
for(auto v:edge[u])//遍历与u相连的每一个点 等价于 for(int i = 0;i<edge[u].size();i++) v = edge[u][i]
{
if(v == fa)
{
continue;
}
dfs(v,u);
int now = dis1[v] +1;//这条路径的长度
if(now>dis1[u])//大于最长路分别更新最长路和次长路
{
dis2[u] = dis1[u];
dis1[u] = now;
}
else if(now > dis2[u])//大于次长路更新次长路
{
dis2[u] = now;
}
} max_d = max(max_d,dis1[u] + dis2[u]);//最后一条经过u的路径的最大长度即为最长路加次长路
}
signed main()
{
//测试用
#if _clang_
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif read(n);
int u,v;
for(int i = 1;i<n;i++)
{
read(u),read(v);
//分别加边
e.push_back({u,v});
edge[u].push_back(v);
edge[v].push_back(u);
}
int d1 = 0,d2 = 0,ans = 0;
for(int i = 1;i<n;i++)
{
//一定要初始化!
memset(dis1,0,sizeof(dis1));
memset(dis2,0,sizeof(dis2));
max_d = 0;
//找e[i-1].first所在子树的直径
dfs(e[i-1].first,e[i-1].second);
d1 = max_d;
////找e[i-1].second所在子树的直径
max_d = 0;
dfs(e[i-1].second,e[i-1].first);
d2 = max_d;
ans = max(ans,d1*d2);
}
writeln(ans);
return 0;
}

最新文章

  1. web 项目 连接mycat 读写分离失效问题,
  2. CSS3回执特殊图形
  3. Delphi 获取临时数据集 ClientDataSet
  4. Spark入门实战系列--8.Spark MLlib(上)--机器学习及SparkMLlib简介
  5. mongodb 常用命令
  6. Help Me Escape (ZOJ 3640)
  7. WPF 一个弧形手势提示动画
  8. hadoop的wordcount例子运行
  9. PHP-FPM的STATUS显示配置
  10. relative与absolute相结合
  11. c++ anonymous union,struct -- 匿名联合体和机构体
  12. [UWP]了解模板化控件(9):UI指南
  13. ⑦bootstrap按钮 图片 辅助使用基础案例
  14. 对于String 与StringBuffer 和StringBuilder的总结
  15. 或许你不知道的10条SQL技巧
  16. iOS学习之--字符串的删除替换(字符串的常用处理,删除,替换)
  17. 多CPU,多核,多进程,多线程
  18. 国外IOS UI指南
  19. SharePoint JavaScript API in application pages
  20. pycharm、webstorm和idea激活码

热门文章

  1. 算法学习笔记(8.1): 网络最大流算法 EK, Dinic, ISAP
  2. 过年必备!亲戚计算器「GitHub 热点速览 v.23.02」
  3. group by 语句怎么优化?
  4. Atcoder dp I Coins 题解
  5. prettier+ts+eslint+vscode配置代码保存自动格式化,自动remove unsed declaration,delete no-unused-imports
  6. 使用iframe引入文件后设置响应式宽高以及其他问题解决;
  7. U3D编辑器开发&amp;粒子特效/动画预览器示例
  8. Docker+nginx部署前后端分离项目
  9. 云端智创 | 批量化生产,如何利用Timeline快速合成短视频?
  10. webrtc QOS笔记一 Neteq直方图算法浅读