daimayuan(代码源oj)最长路径(树形dp,无向树换根dp)

简介: daimayuan(代码源oj)最长路径(树形dp,无向树换根dp)

题目传送门

/*********************************************************************
    程序名:
    版权: Joecai
    作者: Joecai
    日期: 2022-04-14 19:16
    说明:
*********************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
//#define int long long
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
int n;
vector<int>g[N];
int  f[N][2][2];//以i为子树的最长路径和第二长路径 和他们的点
int v[N];//v[y] 记录了 y 号点的父亲 x 号点作为它的子树时从里面连上来的到 y 号点的最长路径
void dfs(int i, int fa)
{
  for (auto j : g[i])
  {
    if (j == fa) continue;
    dfs(j, i);
    if (f[j][0][0] + 1 > f[i][0][0])
    {
      f[i][1][0] = f[i][0][0], f[i][1][1] = f[i][0][1], f[i][0][0] = f[j][0][0] + 1, f[i][0][1] = j;
    } else if (f[j][0][0] + 1 > f[i][1][0])
    {
      f[i][1][1] = j, f[i][1][0] = f[j][0][0] + 1;
    }
  }
}
void dfs1(int i, int fa)
{
  for (auto j : g[i])
  {
    if (j == fa) continue;
    if (f[i][0][1] == j)
    {
      v[j] = 1 + max(f[i][1][0], v[i]);
    } else
    {
      v[j] = 1 + max(f[i][0][0], v[i]);
    }
    dfs1(j, i);
  }
}
void solve()
{
  cin >> n;
  for (int i = 1; i <= n - 1; i++)
  {
    int x, y;
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  dfs(1, 0);
  dfs1(1, 0);
  for (int i = 1; i <= n; i++)
  {
    cout << f[i][1][0] + f[i][0][0] + v[i] - min({f[i][1][0], f[i][0][0], v[i]}) << endl;;
  }
}
signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  //#ifdef LOCAL
  //freopen("data.in.txt","r",stdin);
  //freopen("data.out.txt","w",stdout);
  //#endif
  int __ = 1;
  //cin>>__;
  while (__--)
  {
    solve();
  }
  return 0;
}


目录
相关文章
|
9月前
【每日一题Day300】LC2236判断根结点是否等于子结点之和
【每日一题Day300】LC2236判断根结点是否等于子结点之和
43 0
|
9月前
|
人工智能 BI
【每日一题Day267】LC834树中距离之和 | 换根dp
【每日一题Day267】LC834树中距离之和 | 换根dp
55 0
|
9月前
【每日一题Day214】LC1080根到叶路径上的不足节点 | 递归
【每日一题Day214】LC1080根到叶路径上的不足节点 | 递归
56 0
|
9月前
|
人工智能 BI
【每日一题Day232】LC2699修改图中的边权 |最短路径
【每日一题Day232】LC2699修改图中的边权 |最短路径
53 0
|
9月前
树形dp常见类型——换根dp
树形dp常见类型——换根dp
力扣1496 判断路径是否相交
力扣1496 判断路径是否相交
|
9月前
【每日一题Day367】LC117填充每个节点的下一个右侧节点指针II | BFS
【每日一题Day367】LC117填充每个节点的下一个右侧节点指针II | BFS
54 1
|
9月前
|
机器学习/深度学习
【每日一题Day181】LC1026节点与其祖先之间的最大差值 | 树形dp
【每日一题Day181】LC1026节点与其祖先之间的最大差值 | 树形dp
56 0
|
算法
【算法真题 一】满二叉搜索树求三个节点的最低公共祖先
【算法真题 一】满二叉搜索树求三个节点的最低公共祖先
115 0
剑指offer 76. 树中两个结点的最低公共祖先
剑指offer 76. 树中两个结点的最低公共祖先
79 0