zoukankan      html  css  js  c++  java
  • hiho 1050 树中的最长路 (树的直径)

      最近在复习比较简单的知识,顺便当整理代码吧。

      树的直径是一个经典问题,即求树上最远两点的距离。

    思路一:

      任取一个点,求这个点的最远点的最远点,两遍bfs即可。

     代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <string>
     8 #include <queue>
     9 #include <stack>
    10 #include <vector>
    11 #include <map>
    12 #include <set>
    13 #include <functional>
    14 #include <cctype>
    15 #include <time.h>
    16 
    17 using namespace std;
    18 
    19 const int INF = 1<<30;
    20 
    21 struct Graph {
    22     static const int MAXN = (int) 1e5+55;
    23     static const int MAXM = MAXN*2;
    24 
    25     int head[MAXN];
    26     int next[MAXM], to[MAXM], use;
    27 
    28     inline void init() {
    29         memset(head, -1, sizeof(head));
    30         use = 0;
    31     }
    32 
    33     inline void addEdge(int u, int v) {
    34         next[use] = head[u];
    35         to[use] = v;
    36         head[u] = use++;
    37     }
    38 };
    39 
    40 const int MAXN = (int) 1e5+55;
    41 
    42 Graph G;
    43 int Que[MAXN];
    44 int d[MAXN];
    45 int n;
    46 
    47 void bfs(int st) {
    48     memset(d, -1, sizeof(d));
    49     int l = 0, r = 0;
    50     d[st] = 0;
    51     Que[r++] = st;
    52     while (l<r) {
    53         int u = Que[l++];
    54         for (int p = G.head[u]; p != -1; p = G.next[p]) {
    55             int v = G.to[p];
    56             if (d[v]!=-1) continue;
    57             d[v] = d[u] + 1;
    58             Que[r++] = v;
    59         }
    60     }
    61 }
    62 
    63 void solve() {
    64     bfs(1);
    65     bfs(Que[n-1]);
    66     printf("%d
    ", d[Que[n-1]]);
    67 }
    68 
    69 int main() {
    70     #ifdef Phantom01
    71         freopen("1050.txt", "r", stdin);
    72     #endif //Phantom01
    73 
    74     while (scanf("%d", &n)!=EOF) {
    75         G.init();
    76         int u, v;
    77         for (int i = 1; i < n; i++) {
    78             scanf("%d%d", &u, &v);
    79             G.addEdge(u, v);
    80             G.addEdge(v, u);
    81         }
    82         solve();
    83     }
    84 
    85     return 0;
    86 }
    View Code

    另一种思路是树形dp,一棵树中的最长路要么在子树中,要么经过根。枚举每棵子树的最大深度和次大深度即可。

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <string>
     8 #include <queue>
     9 #include <stack>
    10 #include <vector>
    11 #include <map>
    12 #include <set>
    13 #include <functional>
    14 #include <cctype>
    15 #include <time.h>
    16 
    17 using namespace std;
    18 
    19 const int INF = 1<<30;
    20 
    21 struct Graph {
    22     static const int MAXN = (int) 1e5+55;
    23     static const int MAXM = MAXN*2;
    24 
    25     int head[MAXN];
    26     int next[MAXM], to[MAXM], use;
    27 
    28     inline void init() {
    29         memset(head, -1, sizeof(head));
    30         use = 0;
    31     }
    32 
    33     inline void addEdge(int u, int v) {
    34         next[use] = head[u];
    35         to[use] = v;
    36         head[u] = use++;
    37     }
    38 };
    39 
    40 Graph G;
    41 
    42 const int MAXN = (int) 1e5+55;
    43 
    44 int dp[MAXN];
    45 int ans;
    46 
    47 int dfs(int u, int pre, int cnt) {
    48     int fi = 0, se = 0;
    49     int t;
    50 
    51     for (int p = G.head[u]; p != -1; p = G.next[p]) {
    52         int v = G.to[p];
    53         if (v==pre) continue;
    54         t = dfs(v, u, cnt+1);
    55         if (t>fi) { se = fi; fi = t; }
    56         else if (t>se) se = t;
    57     }
    58     ans = max(ans, max(fi+cnt, fi+se));
    59     return fi+1;
    60 }
    61 
    62 int main() {
    63     #ifdef Phantom01
    64         freopen("1050.txt", "r", stdin);
    65     #endif //Phantom01
    66 
    67     int n, u, v;
    68     while (scanf("%d", &n)!=EOF) {
    69         G.init();
    70         for (int i = 1; i < n; i++) {
    71             scanf("%d%d", &u, &v);
    72             G.addEdge(u, v);
    73             G.addEdge(v, u);
    74         }
    75         ans = 0;
    76         dfs(1, 1, 0);
    77         printf("%d
    ", ans);
    78     }
    79 
    80     return 0;
    81 }
    View Code


    顺便说一下,hiho上这个题的数据比较弱,开始我几个错误的代码都A了。

  • 相关阅读:
    使用element-ui组件el-table时需要修改某一行样式(包含解决样式无效的问题)或某一列的样式
    面试题:线程A打印1-10数字,打印到第5个数字时,通知线程B
    面试题:不使用数学库求平方根
    Springboot2.x集成Redis集群模式
    Springboot2.x集成Redis哨兵模式
    Springboot2.x集成单节点Redis
    基本算法:冒泡排序算法
    Redis进阶:Redis的哨兵模式搭建
    Redis进阶:Redis的主从复制机制
    Redis的消息订阅及发布及事务机制
  • 原文地址:https://www.cnblogs.com/Phantom01/p/4047229.html
Copyright © 2011-2022 走看看