Codeforces Round #798 C(树上DP)

本文介绍了一种利用深度优先搜索(DFS)进行树形结构优化的方法,通过预处理节点数量和状态转移方程求解每个节点最优决策后不被感染的节点个数。代码展示了如何构建并解决这个问题,适用于树形结构的数据处理和决策优化场景。

首先预处理一下每棵子树的节点个数(sum[]),ans[ ]数组中保存该节点所最优决策后不被感染的结点个数。

状态转移方程

ans[u]=max(ans[u],s-ans[v]+sum[v]-1)

dp中更新子节点所有ans值并得到它们的和,则s-ans[v]+sum[v]-1表示选择了节点u后所不被感染的节点个数,遍历其所有子节点即可的到最优解。

// #pragma GCC optimize (2)
// #pragma G++ optimize (2)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define endl '\n'
#define int long long
#define lowbit(x) x &(-x)
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define TLE(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
vector<int>edge[N];
int sum[N],ans[N];
int  dfs(int x,int p)//预处理sum数组
{
    sum[x]=1;
    for(auto t:edge[x])if(t!=p)
    {
        sum[x]+=dfs(t,x);
    }
    return sum[x];
}
int dp(int x,int p)
{
    int s=0;
    for(auto t:edge[x])if(t!=p)
    {
        s+=dp(t,x);
    }
    for(auto t:edge[x])if(t!=p)
    {
        ans[x]=max(ans[x],sum[t]-1+s-ans[t]);
    }
    return ans[x];
}
void solve()
{
    int n;
    cin>>n;
    rep(i,1,n){edge[i].clear(),sum[i]=0;ans[i]=0;}
    for(int i=1;i<=n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        edge[a].push_back(b);
        edge[b].push_back(a);
        sum[i]=0;
    }
    dfs(1,0);
    cout<<dp(1,0)<<endl;
}
signed main()
{
    TLE();
    int T;
    //T = 1;
    cin>>T;
    while (T--)
        solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值