正题

题目链接:https://www.luogu.com.cn/problem/P5895


题目大意

nnn个点的一个森林,加入若干条长度为LLL的边使它变成一个树,求这棵树的最小直径。


解题思路

显然最优情况一定是以某个节点作为中间展开的一个菊花图(每棵树看做一个点)。

而且每个被连接的节点一定是树上的一个节点满足离它最远的节点最近。我们的定义这个距离为这棵树的半径rrr。

那么答案分为三种情况(以下的rrr按照大小排序)

  1. 某棵树的直径
  2. r1+r2+lr_1+r_2+lr1​+r2​+l(r1r_1r1​的树作为中心,r2r_2r2​连接这个点)
  3. r2+r3+l∗2r_2+r_3+l*2r2​+r3​+l∗2(r1r_1r1​的树作为中心,直径跨越这个中间点)

然后树形dpdpdp求解即可,时间复杂度O(n)O(n)O(n)


codecodecode

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
struct node{int to,next,w;
}a[N*2];
int l,n,m,ans,tot,cnt,tmp,r[N],g[N],f[N],ls[N],fr[N];
bool v[N];
void addl(int x,int y,int w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;return;
}
void dfs(int x,int fa){v[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa)continue;dfs(y,x);if(f[y]+a[i].w>f[x])g[x]=f[x],f[x]=f[y]+a[i].w,fr[x]=y;else if(f[y]+a[i].w>g[x])g[x]=f[y]+a[i].w;}ans=max(ans,f[x]+g[x]);return;
}
void dp(int x,int fa){tmp=min(tmp,f[x]);for(int i=ls[x];i;i=a[i].next){int y=a[i].to,w;if(y==fa)continue;if(y==fr[x])w=g[x]+a[i].w;else w=f[x]+a[i].w;if(w>f[y])g[y]=f[y],f[y]=w,fr[y]=x;else if(w>g[y])g[y]=w;dp(y,x);}return;
}
int main()
{scanf("%d%d%d",&n,&m,&l);for(int i=1;i<=m;i++){   int x,y,w;scanf("%d%d%d",&x,&y,&w);x++;y++;addl(x,y,w);addl(y,x,w);}for(int i=1;i<=n;i++){if(v[i])continue;dfs(i,0);tmp=2147483647;dp(i,0);r[++cnt]=tmp;}sort(r+1,r+1+cnt);if(cnt>=2)ans=max(ans,r[cnt]+r[cnt-1]+l);if(cnt>=3)ans=max(ans,r[cnt-1]+r[cnt-2]+l*2);printf("%d\n",ans);return 0;
}

P5895-[IOI2013]dreaming梦想【树的直径,结论】相关推荐

  1. Codeforces 337D Book of Evil:树的直径【结论】

    题目链接:http://codeforces.com/problemset/problem/337/D 题意: 给你一棵树,n个节点. 如果一个节点处放着"罪恶之书",那么它会影响 ...

  2. [51nod] 1766树上的最远点对 树的直径 树剖LCA+ST表静态查询

    题意: 给你一棵带权树,q次查询,每次给出两个区间,[l1,r1][l2,r2][l_1,r_1] [l_2,r_2][l1​,r1​][l2​,r2​]从这两个区间中分别选择两个数字,使得这两个点的 ...

  3. 牛客题霸 [ 树的直径] C++题解/答案

    牛客题霸 [ 树的直径] C++题解/答案 题目描述 给定一棵树,求出这棵树的直径,即两个节点距离的最大值. 题解: 不知道大家听没听过一个结论: 树的直径可以通过两边dfs找到 步骤: 1.从任意一 ...

  4. 树的直径,树的最长路dp思想

    dp一直弱死了,树型dp很多基本的题都不会,最近在刷树型dp的题,把关于树的最长路的思想总结一下: 树的直径:树中距离最远的两点间的距离. 下面说几道题: hdu 2196:对于树上(双向边)的每一个 ...

  5. 【HDU - 5886】Tower Defence(树的直径,思维,dp)

    题干: There was a civil war between two factions in Skyrim, a province of the Empire on the continent ...

  6. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  7. POJ 1849 Two(树的直径+思维)

    题目链接:http://poj.org/problem?id=1849        题意是有n个点,n-1条边(树形图),在s点放两个机器人,问这两个机器人遍历完所有的点的最少花费(不用回到原点). ...

  8. 树的直径,树的重心,树的分冶

    主要是利用了反证法: 假设 s-t这条路径为树的直径,或者称为树上的最长路 现有结论,从任意一点u出发搜到的最远的点一定是s.t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两 ...

  9. 树形结构——树的直径

    树的直径的定义  树的直径:树上最远两点(叶子结点)的距离. 树的直径的求法 例题:[模板]树的直径 两遍暴力dfs 引理:对于树上任意一点 P P P,找到离它最远的节点 Q Q Q.在找到离节点 ...

最新文章

  1. STM32 基础系列教程 34 - Lwip_tcp_server
  2. PS菜鸟入门 -- 窗口
  3. 2021杭州高考杭二成绩查询,2021年杭州重点高中名单及排名,杭州高中高考成绩排名榜...
  4. SAP Spartacus翻译 i18n - internationalization 的工作原理
  5. EASYUI+MVC4通用权限管理平台
  6. MATLAB基础教程(2) 语言基础知识
  7. python fortran混合编程_python调用fortran模块
  8. 9.FreeRTOS学习笔记-任务通知
  9. python的celery的面试_面试必问的celery,你了解多少?
  10. Uncaught TypeError: this.canvas.getContext is not a function
  11. gnome-terminal 快捷键
  12. hystrix熔断器之command实现
  13. Python基础教程(入门教程),30分钟玩转Python编程!
  14. 5.1索引压缩-词项的统计特性(Heaps定律、Zipf定律)
  15. 外汇风险管理:德鲁克日志之五月十一日
  16. 学习记录609@python实现数据样本的过采样与欠采样
  17. Oracle 锁表查询
  18. 一个屌丝程序员的青春(二二三)
  19. pytorch操作基礎(二)——基礎
  20. mindray心电监护仪使用说明_迈瑞心电监护仪说明书

热门文章

  1. java map 值排序_使用Java8 Stream API对Map类型按照键或值进行排序
  2. 用wxpython做ui_wxPython - 如何强制UI刷新?
  3. php-fpm 超时,PHP超时的坑
  4. 项目管理六大制约因素_用PCTS理念做好项目管理规划(优秀项目管理者必知)...
  5. 面试必问系列之在浏览器中输入URL后到网页显示 其间发生了什么?
  6. java中nextLine(),读取换行符的解决
  7. 《C++ Primer》13.1.4节练习
  8. C++实现线段树(lazy-tag方法)-区间修改,区间查询
  9. Piggy-Bank POJ - 1384(完全背包+背包放满)
  10. Shaolin HDU - 4585(map模板题)