[CF 1238F] The Maximum Subtree 树DP

题意

给定一颗树,求这个树的最大子树,且这个子树是一个good-tree。

good-tree的定义是:每个节点可以表示成一个数值区间,而树上的边表示两个点表示的数值区间相交。

题解

通过分析可以发现,这个子树是这个树的一条链,然后允许这条链上的点带上直接连接的点。

然后就转化为树上求最长链的DP问题。

// #pragma GCC optimize(2)
// #pragma GCC optimize(3)
// #pragma GCC optimize(4)
#include 
//#include 
//#include 
// #include
// using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair pll;

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;


template
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}

/**********showtime************/
            const int maxn = 3e5+9;
            vector<int>mp[maxn];
            int dp[maxn];
            int ans = 0;

            void dfs(int u, int fa) {
                int sz = mp[u].size();
                dp[u] = sz;
                for(int v : mp[u]) {
                    if(v == fa) continue;
                    dfs(v, u);
                    ans = max(ans, dp[u] + dp[v]);
                    dp[u] = max(dp[u], dp[v] + sz - 1);
                }
            }
int main(){
            int T;  scanf("%d", &T);
            while(T--) {
                int n;  scanf("%d", &n);
                for(int i=1; i<=n; i++) mp[i].clear();
                for(int i=1; i) {
                    int u, v;
                    scanf("%d%d", &u, &v);
                    mp[u].pb(v);
                    mp[v].pb(u);
                }
                ans = 0;
                dfs(1,  1);
                printf("%d\n", ans);
            }
            return 0;
}
View Code

你可能感兴趣的:([CF 1238F] The Maximum Subtree 树DP)