题目描述
输入
输出
样例输入
7
6 2
3 4
2 3
1 2
7 6
5 6
样例输出
4
分析:
树上DP。
dp[i][0]表示不选i,以i为根的子树的最大答案。
dp[i][1]表示选i,以i为根的子树的最大答案。
状态转移方程:dp[i][0]=∑max(dp[j][0],dp[j][1]),dp[i][1]=1+∑f[dp][0]
#include <iostream> #include <string> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <deque> #include <map> #define range(i,a,b) for(int i=a;i<=b;++i) #define LL long long #define rerange(i,a,b) for(int i=a;i>=b;--i) #define fill(arr,tmp) memset(arr,tmp,sizeof(arr)) using namespace std; pair<int,int>e[150005]; int tol,h[50005],dp[50005][2],n; void add_edge(int x,int y){e[++tol].first=y;e[tol].second=h[x];h[x]=tol; } void init() {cin>>n;range(i,1,n-1){int x,y;cin>>x>>y;add_edge(x,y);add_edge(y,x);} } void dfs(int x,int fu){dp[x][1]=1,dp[x][0]=0;for(int i=h[x];i;i=e[i].second){int fir=e[i].first;if(fir==fu)continue;dfs(fir,x);dp[x][1]+=dp[fir][0];dp[x][0]+=max(dp[fir][1],dp[fir][0]);} } void solve(){dfs(1,0);cout<<max(dp[1][0],dp[1][1])<<endl; } int main() {init();solve();return 0; }