#include <stdio.h> #include <algorithm> #include <string.h> #include <vector> using namespace std; int m, n, vis[11000]; long long dp[11000], v[11000]; vector<int>Q[11000]; long long dfs(int start) { int len; len = Q[start].size(); if(len==0) { return v[start]; } long long sum = 0; int i; for(i=0; i<len; i++) { int u = Q[start][i]; if(vis[u]==0) { vis[u] = 1; sum+=dfs(u); } } return max(v[start], sum); } int main() { int T, a, b; scanf("%d", &T); while(T--) { scanf("%d %d", &m, &n); for(int i=1; i<=m; i++) { scanf("%lld", &v[i]); Q[i].clear(); } for(int i=1; i<m; i++) { scanf("%d %d", &a, &b); Q[a].push_back(b); Q[b].push_back(a); } memset(vis, 0, sizeof(vis)); vis[n] = 1; memset(dp, 0, sizeof(dp)); long long ans = dfs(n); printf("%lld ", ans); } return 0; } /** 50 7 1 40 40 40 20 30 20 30 1 2 1 3 2 4 2 5 3 6 3 7 **/
进入一个房间后有两种选择,1:拿走此房间宝藏,后面的不要了;2:此房间宝藏放弃,拿走与此房间相连的所有其他房间的宝藏;
这样两种选择取最大值即可,用递归的回溯判断更方便。此题数据有坑,题面也没给数据范围,然而int却过不掉。