首页 > 其他分享 >D48 树的直径 P3304 [SDOI2013] 直径

D48 树的直径 P3304 [SDOI2013] 直径

时间:2024-09-10 09:52:18浏览次数:14  
标签:int P3304 D48 SDOI2013 直径 include mxd

视频链接:

 

P3304 [SDOI2013] 直径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 两次 DFS O(n)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;
const int N=200005;
struct edge{
  int to,w,ne;
}e[N<<1];
int head[N],idx;
void add(int x,int y,int w){
  e[++idx]={y,w,head[x]};
  head[x]=idx;
}
int n,p,l,r,pre[N],col[N];
ll d[N],mxd;

void dfs(int x,int fa){
  pre[x]=fa;
  for(int i=head[x];i;i=e[i].ne){
    int y=e[i].to,w=e[i].w;
    if(y==fa) continue;
    d[y]=d[x]+w;
    if(d[y]>mxd) mxd=d[y],p=y;
    dfs(y,x);
  }
}
void dfs2(int x,int fa){
  for(int i=head[x];i;i=e[i].ne){
    int y=e[i].to,w=e[i].w;
    if(col[y]||y==fa) continue;
    d[y]=d[x]+w;
    if(d[y]>mxd) mxd=d[y];
    dfs2(y,x);
  }
}
int main(){
  scanf("%d",&n);
  for(int i=1,x,y,z;i<n;i++){
    scanf("%d%d%d",&x,&y,&z);
    add(x,y,z); add(y,x,z);
  }
  dfs(1,0);
  d[p]=mxd=0; l=p; //记录直径左端点
  dfs(p,0);
  r=p; //记录直径右端点
  printf("%lld\n",mxd);
  
  for(int i=r;i;i=pre[i])col[i]=1; //标记直径
  int ll=l,rr=r;
  for(int i=pre[rr];i!=ll;i=pre[i]){
    int ld=d[i],rd=d[rr]-d[i];
    d[i]=mxd=0;
    dfs2(i,0);
    if(mxd==rd) r=i;
    if(mxd==ld){l=i;break;}
  } //区间[l,r]为公共路径
  if(l==r) puts("0");
  else{
    int cnt=1;
    for(int i=pre[r];i!=l;i=pre[i]) cnt++;
    printf("%d\n",cnt);
  }
}

 

标签:int,P3304,D48,SDOI2013,直径,include,mxd
From: https://www.cnblogs.com/dx123/p/18402132

相关文章

  • 二叉树的直径(LeetCode)
    题目给你一棵二叉树的根节点,返回该树的 直径 。二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。两节点之间路径的 长度 由它们之间边数表示。解题classTreeNode:def__init__(self,val=0,left=......
  • 分享丨【题单】链表、二叉树与一般树(前后指针/快慢指针/DFS/BFS/直径/LCA)
    作者:灵茶山艾府链接:https://leetcode.cn/circle/discuss/K0n2gO/一、链表注:由于周赛中的链表题可以转成数组处理,难度比直接处理链表低,故不标明难度分。带着问题去做下面的题目:在什么情况下,要用到哨兵节点(dummynode)?在什么情况下,循环条件要写while(node!=null)?什么情况......
  • 树的直径
    树的直径即为一棵树上的最长链。一般分为有负权图和无负权图来考虑。无负权只需做两次dfs。第一次是搜索出从任一点出发到达的最远的点P,那么这个点就一定在最长链上(请自证)。第二次搜索从点P出发到达的最远的点Q,那么最长链即为P与Q的距离。题目:B4016树的直径代码:点击查看......
  • 树的直径
    树的直径树上任意两节点之间最长的简单路径即为树的直径。即树上最长的链显然树可以有多条直径SPOJPT07Z模版树的直径两种求法,时间复杂度均为\(O(n)\)常用的是两遍dfs第一遍dfs从任一点开始,找到可以到达的最远点,这个最远点就是直径的一个端点,第二遍dfs再从这一端点出发,再......
  • AcWing 1078. 旅游规划 (DFS找树的直径+直径中点性质求解,无DP)
    原题链接题目描述算法引用自树的直径-OI-Wiki:若树上所有边边权均为正,则树的所有直径中点重合证明:使用反证法。设两条中点不重合的直径分别为\(\delta(s,t)与\delta(s',t')\),中点分别为\(x\)与\(x'\)。显然,\(\delta(s,x)=\delta(x,t)=\delta(s',x')=\delta(......
  • 『树的直径、重⼼』Day10
    DrazilandMorningExercise\(f\)可以换根求。对于一段乱序序列,你不好求其中max-min的限制。根据重心的性质,如果你让重心为root,那么向下\(f\)一定单减。这样,你就对每个点在末尾的情况,树上倍增找到最大的点,树上差分即可。现在想到了好像可以线段树合并,那么你当前点就......
  • 【题解】Solution Set - NOIP2024集训Day10 树的直径、重⼼、中⼼
    【题解】SolutionSet-NOIP2024集训Day10树的直径、重⼼、中⼼https://www.becoder.com.cn/contest/5464「CF516D」DrazilandMorningExercise首先,我们可以换根求出所有点的\(f\)。然后不会了……思考一下,一条直径提供的到底时什么。实际上,一条直径上的点取到\(f\)......
  • 【算法模板】计算几何:旋转卡壳求凸包直径
    旋转卡壳算法是一种几何算法,主要用于在二维平面上求解与凸包相关的最优问题。该算法利用凸包顶点的顺序性和对称性,通过模拟两个卡壳(calipers)沿着凸包边界的旋转来寻找最优解。常见的应用包括计算凸包的直径(即最远点对之间的距离)、最小包围矩形(最小面积矩形),以及最小宽度(宽度......
  • 【树的直径 求树中距离跟阶段点最远的点】CodeForce1822F.md
    CF1822F-Problem-F-Codeforces题目大意:无根树的每条边为k,定义操作:移动根节点为把当前的根ROOT移动到相邻节点,每次代价为c,定义成本=从ROOT出发到达的最长的路径的长度,利润=成本-代价,求利润最大值\[\begin{align}&\huge\color{red}记得开\text{longlong}\\\\\\&\huge思......
  • 浅谈图论中树及其相关知识点(树的遍历、直径、最近公共祖先)(c++)
    目录前言一.关于树二.树的遍历(一)遍历方式常见遍历1.DFS遍历2.BFS遍历二叉树遍历1.先序遍历2.中序遍历3.后序遍历(二)例题讲解1.P1030[NOIP2001普及组]求先序排列思路AC代码 2.P5908猫猫和企鹅思路AC代码  3.P1395会议思路AC代码三.树的直径(一)定......