daimayuan 三进制循环(树形dp)

简介: daimayuan 三进制循环(树形dp)

题目传送门

这个题目比较简单,思路一下就出来了。

维护两个d p , d p 1 和 d p 2 : dp,dp1和dp2:dpdp1dp2:

d p 1 [ i ] : 以 点 i 为 起 点 以 及 子 树 符 合 取 模 递 增 的 最 大 长 度 dp1[i]:以点i为起点以及子树符合取模递增的最大长度dp1[i]:i

d p 2 [ i ] : 以 点 i 为 起 点 以 及 子 树 符 合 取 模 递 减 的 最 大 长 度 dp2[i]:以点i为起点以及子树符合取模递减的最大长度dp2[i]:i

答案就是:a n s = m a x ( a n s , Σ ( d p 1 [ i ] + d p 2 [ i ] − 1 ) ) ans=max(ans,\Sigma (dp1[i]+dp2[i]-1))ans=max(ans,Σ(dp1[i]+dp2[i]1))

代码:

/*********************************************************************
    程序名:
    版权:
    作者: Joecai
    日期: 2022-05-21 13:19
    说明:
*********************************************************************/
#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 = 5e5 + 10, INF = 0x3f3f3f3f;
int n;
vector<int>g[N];
int w[N];
int dp1[N];//以这个点开始的如0 1 2 0
int dp2[N];
int ans = 0;
void  dfs(int u, int fa)
{
  dp1[u] = 1;
  dp2[u] = 1;
  for (auto x : g[u])
    {
      if (x == fa)
        continue;
      dfs(x, u);
      if ((w[x]) % 3 == (w[u] + 1) % 3)
        {
          dp1[u] = max(dp1[u], dp1[x] + 1);
        }
      if (w[x] % 3 == (w[u] - 1 + 3) % 3)
        {
          dp2[u] = max(dp2[u], dp2[x] + 1);
        }
    }
  ans = max(dp1[u] + dp2[u] - 1, ans);
}
void solve()
{
  cin >> n;
  for (int i = 1; i < n; i++)
    {
      int a, b;
      cin >> a >> b;
      g[a].push_back(b);
      g[b].push_back(a);
    }
  for (int i = 1; i <= n; i++)
    {
      cin >> w[i];
    }
  dfs(1, -1);
  cout << ans << 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;
}


目录
相关文章
|
7月前
|
C语言
C语言之回文数的求解。回文数一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
C语言之回文数的求解。回文数一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
|
4月前
两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。 比如,11/13=6=>0.846153846153… 其循环节为[846153] 共有6位。
两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。 比如,11/13=6=>0.846153846153… 其循环节为[846153] 共有6位。
|
10月前
位运算判断奇数or偶数
位运算判断奇数or偶数
|
5月前
|
存储 算法
【LeetCode】每日一题&最后一个单词的长度&投票法求解多数元素&异或操作符巧解只出现一次的数字&整数反转
【LeetCode】每日一题&最后一个单词的长度&投票法求解多数元素&异或操作符巧解只出现一次的数字&整数反转
|
5月前
|
算法 测试技术 C#
C++二分算法的应用:乘法表中第k小的数
C++二分算法的应用:乘法表中第k小的数
|
5月前
|
算法 测试技术 C#
C++二分查找算法的应用:最小好进制
C++二分查找算法的应用:最小好进制
|
7月前
|
算法
【Leetcode-190.颠倒二进制位 -191.位1的个数 -202.快乐数】
【Leetcode-190.颠倒二进制位 -191.位1的个数 -202.快乐数】
26 0
|
10月前
|
算法 C语言 C++
【二分查找】668. 乘法表中第k小的数
【二分查找】668. 乘法表中第k小的数 在另一篇博客里讲过二分法的模板: 《二分法的模板讲解》
56 0
|
11月前
|
存储 算法 Java
leetcode刷题记录:7.整数反转,8.字符串转整数,9.回文数
leetcode刷题记录:7.整数反转,8.字符串转整数,9.回文数
39 0
|
11月前
|
人工智能 C++
acwing 712 正数 C++循环得到输入的以及获取数组长度
acwing 712 正数 C++循环得到输入的以及获取数组长度
41 1