キャタピラーツリーDP

ポータル

タイトル説明

リンクには何も言わない

分析

まず、キャタピラーはメインチェーンであり、メインチェーンに直接接続されているすべてのポイントがあります

f [u]を使用して、uが頂点のときに形成される最大の毛虫を表します。次に、uに接続された点vを見つけ、最大のf [v]を見つける必要があります。これにより、状態遷移方程式
f [u] = fを簡単に記述できます。[v] + 1 + max(0、cnt-1);
cntは、uに直接接続されているポイントです。
この状態遷移方程式は、理解しやすいはずです。さらに、このポイントに加えて、最大のキャタピラーに表示されない他のポイントもあります。直接接続されたポイント

次に、各ポイントが頂点であるときに生成される最大のキャタピラーと2番目に大きいキャタピラーを維持するだけで済みます。

コード

#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 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/

おすすめ

転載: blog.csdn.net/tlyzxc/article/details/112426701