zoukankan      html  css  js  c++  java
  • 【模板】tyvjP1520 树的直径 [2017年5月计划 清北学堂51精英班Day3]

    P1520 树的直径
    时间: 1000ms / 空间: 131072KiB / Java类名: Main

    描述

    树的直径,即这棵树中距离最远的两个结点的距离。每两个相邻的结点的距离为1,即父亲结点与儿子结点或儿子结点与父子结点之间的距离为1.有趣的是,从树 的任意一个结点a出发,走到距离最远的结点b,再从结点b出发,能够走的最远距离,就是树的直径。树中相邻两个结点的距离为1。你的任务是:给定一棵树, 求这棵树中距离最远的两个结点的距离。

    输入格式

    输入共n行
    第一行是一个正整数n,表示这棵树的结点数
    接下来的n-1行,每行三个正整数a,b,w。表示结点a和结点b之间有一条边,长度为w
    数据保证一定是一棵树,不必判错。

    输出格式

    输出共一行
    第一行仅一个数,表示这棵树的最远距离

    测试样例1

    输入

    4
    1 2 10
    1 3 12
    1 4 15

    输出

    27

    备注

    10%的数据满足1<=n<=5
    40%的数据满足1<=n<=100
    100%的数据满足1<=n<=10000 1<=a,b<=n 1<=w<=10000Tgotmacp
     
     
    两种方法。
     
    第一种钦定一个根节点,以香港记者的速度跑一边BFS并找到最长链。
    然后钦定最长链的终点为根,再以香港记者的速度跑一边BFS,找到的最长链就是直径。
     
    第二种钦定一个根节点,dfs或dfs,从下往上,记dp1[i]为节点i下面子树的最长链长,dp2[i]为节点i下面子树的次长链长,答案是两个加和。
     
    求-1s
     
    方法1:
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define max(a,b) ((a) > (b) ? (a) : (b))
     7 #define min(a,b) ((a) > (b) ? (b) : (a))
     8 #define lowbit(a) ((a) & (-(a)))
     9 
    10 int read()
    11 {
    12     int x = 0;char ch = getchar();char c = ch;
    13     while(ch > '9' || ch < '0')c = ch, ch = getchar();
    14     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    15     if(c == '-')return -x;
    16     return x;
    17 }
    18 
    19 const int INF = 0x3f3f3f3f;
    20 const int MAXN = 10000 + 10;
    21 const int MAXE = MAXN * 2;
    22 
    23 int head[MAXN];
    24 int cnt;
    25 int n;
    26 int tmp1,tmp2,tmp3;
    27 struct Edge
    28 {
    29     int u,v,w,next;
    30 }edge[MAXE];
    31 inline void insert(int a,int b,int c)
    32 {
    33     edge[++cnt] = Edge{a,b,c,head[a]};
    34     head[a] = cnt;
    35 }
    36 inline void init()
    37 {
    38     n = read();
    39     for(int i = 1;i < n;i ++)
    40     {
    41         tmp1 = read();tmp2 = read();tmp3 = read();
    42         insert(tmp1, tmp2, tmp3);
    43         insert(tmp2, tmp1, tmp3);
    44     } 
    45 }
    46 
    47 int queue[MAXN];
    48 int ans;
    49 bool b[MAXN];
    50 int lenth[MAXN];//lenth[i]表示节点i到根节点的长度 
    51 int bfs(int root)
    52 {
    53     memset(queue, 0, sizeof(queue));
    54     memset(b, 0, sizeof(b));
    55     int head = 1,tail = 1;
    56     int a = 1;
    57     queue[tail] = root;
    58     lenth[root] = 0;
    59     b[root] = true;
    60     
    61     int mnode = root,m = 0;
    62     do
    63     {
    64         int x = queue[head];
    65         head ++;
    66         for(int pos = ::head[x];pos;pos = edge[pos].next)
    67         {
    68             int tmp = edge[pos].v;
    69             if(!b[tmp])
    70             {
    71                 b[tmp] = true;
    72                 queue[++tail] = tmp;
    73                 lenth[tmp] = lenth[x] + edge[pos].w;
    74                 if(lenth[tmp] > m)m = lenth[tmp],mnode = tmp;
    75                 a ++;
    76             }
    77         }
    78     }while(a < n); 
    79     ans = max(ans, m);
    80     return mnode;
    81 }
    82 inline void work()
    83 {
    84     bfs(bfs(1));
    85 }
    86 inline void shuchu()
    87 {
    88     printf("%d", ans);
    89 }
    90 int main()
    91 {
    92     init();
    93     work();
    94     shuchu();
    95     return 0;
    96 }
     

    方法2:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <algorithm>
      6 #define max(a,b) ((a) > (b) ? (a) : (b))
      7 #define min(a,b) ((a) > (b) ? (b) : (a))
      8 #define lowbit(a) ((a) & (-(a)))
      9 
     10 int read()
     11 {
     12     int x = 0;char ch = getchar();char c = ch;
     13     while(ch > '9' || ch < '0')c = ch, ch = getchar();
     14     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     15     if(c == '-')return -x;
     16     return x;
     17 }
     18 
     19 const int INF = 0x3f3f3f3f;
     20 const int MAXN = 10000 + 10;
     21 const int MAXE = MAXN * 2;
     22 
     23 int head[MAXN];
     24 int cnt;
     25 int n;
     26 int tmp1,tmp2,tmp3;
     27 struct Edge
     28 {
     29     int u,v,w,next;
     30 }edge[MAXE];
     31 inline void insert(int a,int b,int c)
     32 {
     33     edge[++cnt] = Edge{a,b,c,head[a]};
     34     head[a] = cnt;
     35 }
     36 inline void init()
     37 {
     38     n = read();
     39     for(int i = 1;i < n;i ++)
     40     {
     41         tmp1 = read();tmp2 = read();tmp3 = read();
     42         insert(tmp1, tmp2, tmp3);
     43         insert(tmp2, tmp1, tmp3);
     44     } 
     45 }
     46 
     47 int queue[MAXN];
     48 int ans;
     49 bool b[MAXN];
     50 int dp1[MAXN];//最长路
     51 int dp2[MAXN];//次长路 
     52 int lenth[MAXN];//lenth[i]表示节点i到根节点的长度 
     53 void bfs(int root)
     54 {
     55     int head = 1,tail = 1;
     56     int a = 1;
     57     queue[tail] = root;
     58     lenth[root] = 0;
     59     b[root] = true;
     60     
     61     int mnode = root,m = 0;
     62     do
     63     {
     64         int x = queue[head];
     65         head ++;
     66         for(int pos = ::head[x];pos;pos = edge[pos].next)
     67         {
     68             int tmp = edge[pos].v;
     69             if(!b[tmp])
     70             {
     71                 b[tmp] = true;
     72                 queue[++tail] = tmp;
     73                 a ++;
     74             }
     75         }
     76     }while(a < n);
     77     for(int i = tail;i >= 1;i --)
     78     {
     79         int x = queue[i];
     80         if(!::head[i])
     81         {
     82             b[i] = false;
     83         }
     84         else
     85         {
     86             int m1 = 0,m2 = 0;
     87             for(int pos = ::head[x];pos;pos = edge[pos].next)
     88             {
     89                 int tmp = edge[pos].v;
     90                 if(!b[tmp])
     91                 {
     92                     if(m1 < dp1[tmp] + edge[pos].w)
     93                     {
     94                         m2 = m1;
     95                         m1 = dp1[tmp] + edge[pos].w;
     96                     } 
     97                     else if(m2 < dp1[tmp] + edge[pos].w)
     98                     {
     99                         m2 = dp1[tmp] + edge[pos].w;
    100                     }
    101                 }
    102             }
    103             dp1[x] = m1;dp2[x] = m2;
    104         }
    105         b[x] = false;
    106         ans = max(ans, dp1[x] + dp2[x]);
    107     }
    108 }
    109 inline void work()
    110 {
    111     bfs(1);
    112 }
    113 inline void shuchu()
    114 {
    115     printf("%d", ans);
    116 }
    117 int main()
    118 {
    119     init();
    120     work();
    121     shuchu();
    122     return 0;
    123 }
     
  • 相关阅读:
    android-自定义View
    java
    记录-常用的开发技巧
    便签:
    zTree 树形控件 ajax动态加载数据
    jquery ajax 传数据到后台乱码的处理方法
    spring + quartz 定时
    SpringMVC + Spring + MyBatis 学习笔记:提交数据遭遇基础类型和日期类型报400错误解决方法
    复制新项目 ,tomcat部署时名字还是旧项目名
    jsp 通用获取所有表单值传后台
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/6914312.html
Copyright © 2011-2022 走看看