Think:
1题意:举行聚会,参会人选不希望自己的直属上司参加,关系形成一棵树,参会人选每个人有自己的开心度,求最大开心度
2思路:树形dp + 并查集(寻找根节点)
以下为Accepted代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 6004;
int n, dp[N][2], far[N], vis[N];
void DFS(int u);
int main(){
int i, s, f, root;
while(~scanf("%d", &n)){
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
for(i = 1; i <= n; i++)/*并查集初始化*/
far[i] = i;
for(i = 1; i <= n; i++)
scanf("%d", &dp[i][1]);
while(scanf("%d %d", &s, &f) && (s || f)){
far[s] = f;
}
root = 1;
while(far[root] != root)/*寻找根节点*/
root = far[root];
DFS(root);
printf("%d\n", max(dp[root][1], dp[root][0]));
}
return 0;
}
void DFS(int u){
vis[u] = 1;
for(int i = 1; i <= n; i++){
if((!vis[i]) && far[i] == u){
DFS(i);
dp[u][1] += dp[i][0];/*上属去下属不去*/
dp[u][0] += max(dp[i][1], dp[i][0]);/*上属不去前提下下属去或不去取最大值*/
}
}
}