毛毛虫 树形DP

传送门

题目描述

链接里面都有我就不说了

分析

首先一个毛毛虫,就是一条主链,外加上主链上所有点所直接连接的点

我们用f[u]表示以u为顶点时形成的最大的毛毛虫,那么我们需要找到和u相连的点v,找到最大的f[v],容易写出状态转移方程
f[u] = f[v] + 1 + max(0,cnt - 1);
cnt是与u直接相连的点
这个状态转移方程应该比较好理解,加上自己这个点,再加上其他没有出现在最大子毛毛虫中的直接相连的点即可

然后只需要维护每一个点作为顶点时产生的最大毛毛虫以及次大毛毛虫即可

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 3000010;
int h[N],e[N * 2],ne[N * 2],idx;
int f[N];
int n,m;
int ans;

void add(int x,int y){
    ne[idx] = h[x],e[idx] = y,h[x] = idx++;
}

void dfs(int u,int fa){
    int max1 = 0,max2 = 0;
    int cnt = 0;
    for(int i = h[u];~i;i = ne[i]){
        int j = e[i];
        cnt++;
        if(j == fa) continue;
        dfs(j,u);
        f[u] = max(f[u],f[j]);
        if(f[j] > max1) max2 = max1,max1 = f[j];
        else if(f[j] > max2) max2 = f[j];
    }
    cnt--;
    f[u] += (1 + max(0,cnt - 1));
    ans = max(ans,f[u] + max2);
}

int main(){
    memset(h,-1,sizeof h);
    scanf("%d%d",&n,&m);
    while(m--){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y),add(y,x);
    }
    dfs(1,-1);
    printf("%d\n",max(ans,1));
    return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值