没有上司的舞会
思路
树形dp入门经典题
里面的关系是一个树状的无环图,每个节点我们显然有两种取法,参加派对,不参加派对,所以状态转移方程就出来了
- 参加派对 ,上司参加了舞会,其直系下属不能参加舞会
- 不参加派对 ,上司没有参加舞会,其直系下属可以参加,也可以不参加。
代码
/* Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f; inline ll read() { ll f = 1, x = 0; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f * x; } const int N = 6e3 + 10; vector<int> G[N]; int n, ans, dp[N][2]; void dfs(int rt, int fa) { ans = max(ans, dp[rt][1]); for(int i : G[rt]) { if(i == fa) continue; dfs(i, rt); dp[rt][1] = max(dp[rt][1], dp[rt][1] + dp[i][0]); dp[rt][0] = max({dp[rt][0], dp[i][1] + dp[rt][0], dp[i][0] + dp[rt][0]}); } ans = max(ans, dp[rt][1]); ans = max(ans, dp[rt][0]); } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); n = read(); for(int i = 1; i <= n; i++) { dp[i][1] = read(); } for(int i = 1; i < n; i++) { int x = read(), y = read(); G[x].pb(y); G[y].pb(x); } dfs(1, 0); cout << ans << endl; return 0; }