长沙学院2022暑假训练赛(一):E题

本文介绍了一种使用树形动态规划的方法来解决给定连通图中,寻找权值单调上升的最长路径问题。通过定义dpup和dpdown数组,利用深度优先搜索遍历节点,找出以每个节点为根的最大上升和下降路径长度,最终得到整个路径的最大长度。
摘要由CSDN通过智能技术生成

题意:给你一个连通图,有n-1条边,以及每个点都有一个权值,让你求出权值单调上升的路径的最长长度

思路:树形dp题,用一个数组dpup[i]表示以i为根的的最长上升路径的长度,dpdown[i]表示以i为根的最长下降路径的长度,那么以i为根的路径长度最长就是dpup[i]+dpdown[i]+1,遍历每一个根的节点,用dfs搜索得出最大值

#include <bits/stdc++.h>
using namespace std;
//树形dp,完全没想到
const int N = 1e6 + 10;
int a[N];
int b, c;
int n;
int maxn = 0;
vector<int> v[N];
int dpup[N];   //以节点N为跟的最长上升子序列的长度
int dpdown[N]; //以节点N为跟的最长下降子序列的长度
void dfs(int now, int fuck)
{
    // dpup[1] = 1;
    // dpdown[1] = 1;
    for (auto t : v[now])
    {
        if (t == fuck)
        {
            continue;
        }
        dfs(t, now);
        if (a[t] < a[now])
        {
            dpdown[now] = max(dpdown[t] + 1, dpdown[now]);
        }
        else if (a[t] > a[now])
        {
            dpup[now] = max(dpup[t] + 1, dpup[now]);
        }
    }
    maxn = max(maxn, dpup[now] + dpdown[now] + 1); //加一是因为这里求的是在now上面的和now下面的,但没有包括now本身,这个1就相当于是now
    // printf("%d\n", now);
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n - 1; i++)
    {
        scanf("%d%d", &b, &c);
        v[b].push_back(c);
        v[c].push_back(b);
    }
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
    }
    dfs(1, 1);
    printf("%d\n", maxn);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值