首先预处理一下每棵子树的节点个数(sum[]),ans[ ]数组中保存该节点所最优决策后不被感染的结点个数。
状态转移方程
dp中更新子节点所有ans值并得到它们的和,则表示选择了节点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;
}
本文介绍了一种利用深度优先搜索(DFS)进行树形结构优化的方法,通过预处理节点数量和状态转移方程求解每个节点最优决策后不被感染的节点个数。代码展示了如何构建并解决这个问题,适用于树形结构的数据处理和决策优化场景。

1017

被折叠的 条评论
为什么被折叠?



