zoukankan      html  css  js  c++  java
  • hihocoder1050 树中的最长路径

    问题分析:

    树中的路径,即是从树上的某个节点起,经过某个转折节点,到达另一个节点这样一条路径。而最长路径就是要找出这些路径中最长的那一条。

    算法思路:

    对于每个节点,记录下以该节点为根节点的子树中从该节点开始到所有叶子节点的路径中最长的那一条路径长度d1以及次长的那一条路径长度d2(最长和次长两条路径无公共边)。那么对于我们想要解决的问题(树中的最长路径),就只需要枚举每个节点作为转折节点,求出所有d1+d2中的最大值。

    关于d1,d2的求解:

    对于任意一个节点,其d1值等于其所有子节点最大d1值加1,其d2值等于其除d1值对应的子节点以外的所有子节点最大d1值加1。

    特别的,叶子节点d1=d2=0,对于只有一个儿子的节点,d2=0。

    我的代码:

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <cstring>
     5 
     6 using namespace std;
     7 
     8 #define MAXN 100005
     9 
    10 struct Tree
    11 {
    12     vector<int> v[MAXN];
    13     bool vis[MAXN];
    14     int n, d1[MAXN], d2[MAXN], fa[MAXN];
    15     void init(int _n)
    16     {
    17         n = _n;
    18         for(int i=1; i<=n; ++i) v[i].clear();
    19         memset(&d1[1], 0, n*sizeof(int));
    20         memset(&d2[1], 0, n*sizeof(int));
    21     }
    22     void addEdge(int a, int b)
    23     {
    24         v[a].push_back(b);
    25         v[b].push_back(a);
    26     }
    27     void getFather(int x, int f)
    28     {
    29         fa[x] = f;
    30         vis[x] = true;
    31         for(int i=0; i<v[x].size(); ++i)
    32             if(!vis[v[x][i]]) getFather(v[x][i], x);
    33     }
    34     void post_order(int x)
    35     {
    36         vis[x] = true;
    37         for(int i=0; i<v[x].size(); ++i)
    38             if(!vis[v[x][i]])   post_order(v[x][i]);
    39         int tmp;
    40         for(int i=0; i<v[x].size(); ++i)
    41         {
    42             if(v[x][i]!=fa[x]&&d1[x]<d1[v[x][i]]+1)
    43             {
    44                 d1[x] = d1[v[x][i]]+1;
    45                 tmp = v[x][i];
    46             }
    47         }
    48         for(int i=0; i<v[x].size(); ++i)
    49             if(v[x][i]!=fa[x]&&v[x][i]!=tmp&&d2[x]<d1[v[x][i]]+1)
    50                 d2[x] = d1[v[x][i]]+1;
    51     }
    52     int getAns()
    53     {
    54         int ans = 0;
    55         for(int i=1; i<=n; ++i) ans = max(ans, d1[i]+d2[i]);
    56         return ans;
    57     }
    58 }tree;
    59 
    60 int main()
    61 {
    62     int n, a, b;
    63     while(cin>>n)
    64     {
    65         tree.init(n);
    66         for(int i=0; i<n-1; ++i)
    67         {
    68             cin>>a>>b;
    69             tree.addEdge(a, b);
    70         }
    71         memset(&tree.vis[1], 0, n);
    72         tree.getFather(1, -1);
    73         memset(&tree.vis[1], 0, n);
    74         tree.post_order(1);
    75         cout<<tree.getAns()<<endl;
    76     }
    77 
    78     return 0;
    79 }

    题目来源:http://hihocoder.com/problemset/problem/1050

  • 相关阅读:
    D3.js 几种常用的坐标轴
    前端页面的用户体验优化设计
    用can-fixture拦截Ajax并模拟响应
    webpack入门及使用
    CommonJS和AMD规范
    凝思6.0虚拟机搭建--遇到的问题
    凝思6.0安装vmware tools记录
    linux定时任务crontab命令
    find命令使用指南
    关于字体、字形、字符集、字体大小
  • 原文地址:https://www.cnblogs.com/pczhou/p/4296481.html
Copyright © 2011-2022 走看看