问题描述:
思路概述:
(1)将每个人可以参会的 dp[ i ][ 1 ] 初始化
(2)建立每个人的不可一同参会名单
(3)把第一个人员当做树中心,开始分叉遍历
(4)输出树中心1的参会与否这两种情况的最大值
满分代码:
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> g[112345];
int dp[112345][3];
void dfs(int u,int q)
{
for(int v:g[u])
{
if(v==q)continue;
dp[u][1]+=dp[v][0];
dp[u][0]+=max(dp[v][1],dp[v][0]);
dfs(v,u);
}
return;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>dp[i][1];
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0);
cout<<max(dp[1][1],dp[1][0]);
return 0;
}
代码+批注:
#include<bits/stdc++.h>
using namespace std;
int n;//人员总数量
vector<int> g[112345];//每个人员所对应不能一起参会的名单
int dp[112345][3];//每个人员参会或不参会,所带来的快乐指数
void dfs(int u,int q)
{
for(int v:g[u])
{
if(v==q)continue;//防止重复赋值
dp[u][1]+=dp[v][0];//u参会,v一定不能参会
dp[u][0]+=max(dp[v][1],dp[v][0]);//u不参会,v可以参会可以不参会,取最大
dfs(v,u);//遍历以v为小中心,研究v与g[v]所带来的影响
}
return;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>dp[i][1];
//统计每个人员所对应不能一起参会的名单
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0);//把1当做树中心,开始分叉遍历
cout<<max(dp[1][1],dp[1][0]);//输出遍历结束后,树中心1的参会或不参会的最大值
return 0;
}