码迷,mamicode.com
首页 > 其他好文 > 详细

关于树形结构的一点东西

时间:2019-10-05 18:14:59      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:lse   树形结构   节点   代码   continue   两种   mat   数组   结构   

前言: 考试树形结构太频繁惹菜鸡钧钧屁也不会!(雾

1.树的直径:

众所周知的两种求法:

  • 两遍\(dfs\)
    信奥不需要证明
    第一遍\(dfs\)搜到树的最深叶节点,然后把这个叶节点拎起来作为根再\(dfs\)到最深叶节点。
    *最深指按照边长算距离根节点最远。
    代码:
   void dfs_R1(int x, int fa, int depth) {
    if(depth > Max) Max = depth, Rs = x;
    for(int i = head[x]; i; i = edg[i].nxt) {
      if(edg[i].v == fa) continue;
      dfs_R1(edg[i].v, x, depth + edg[i].w);
    }
  }
   void dfs_R2(int x, int fa, int depth) {
    if(depth > ans) ans = depth, Re = x;
    for(int i = head[x]; i; i = edg[i].nxt) {
      if(edg[i].v == fa) continue;
      dfs_R2(edg[i].v, x, depth + edg[i].w);
    }
  }
  • 树形\(DP\)
    对于每个节点,维护其子树中的最长链和次长链,设数组f[x][1]表示最长链,f[x][2]表示次长链。更新时,若“连接儿子的边\(+\)此儿子子树中的最长链”大于当前最长链,则当前最长链变为次长链,最长链变为连接儿子的边\(+\)此儿子子树中的最长链,若大于次长链小于最长链则只更新次长链。树的直径必然为某一节点子树中的最长链\(+\)次长链。
    代码:

    void dp_R(int x, int fa) {
     for(int i = head[x]; i; i = edg[i].nxt) {
       if(edg[i].v == fa) continue;
       dp_R(edg[i].v, x);
       if(edg[i].w + f[edg[i].v][1] > f[x][1]) 
         f[x][2] = f[x][1], f[x][1] = edg[i].w + f[edg[i].v][1];
       else if(edg[i].w + f[edg[i].v][1] > f[x][2])
         f[x][2] = f[edg[i].v][1] + edg[i].w;
       ans = max(f[x][1] + f[x][2], ans);
     }
    }

关于树形结构的一点东西

标签:lse   树形结构   节点   代码   continue   两种   mat   数组   结构   

原文地址:https://www.cnblogs.com/clickidea/p/11625239.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!