4867: 没有上司的舞会
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 8 Solved: 8
[Submit][Status][Web Board]
Description
有个公司要举行一场晚会。
为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司
(上司的上司,上司的上司的上司……都可以邀请)。
题目
每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。
为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司
(上司的上司,上司的上司的上司……都可以邀请)。
题目
每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。
Input
第1行一个整数N(1<=N<=6000)表示公司的人数。
接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=127)。
接下来每行两个整数L,K。表示第K个人是第L个人的上司。
输入以0 0结束。
接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=127)。
接下来每行两个整数L,K。表示第K个人是第L个人的上司。
输入以0 0结束。
Output
一个数,最大的气氛值和。
Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
Sample Output
5
一般树形dp以节点编号为第一维然后进行dp
设dp[i][0]表示节点i不参加舞会所以其子节点既可以参加舞会又可以不参加所以
dp[i][0]+=max(dp[son][1],dp[son][0])
同理,dp[i][1]+=dp[son][0]
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=6000+10; int dp[maxn][3]; struct my{ int v; int next; }; my bian[maxn*2]; int adj[maxn]; bool vis[maxn]; int w[maxn],n,fa; void myinsert(int u,int v){ bian[++fa].v=v; bian[fa].next=adj[u]; adj[u]=fa; } void dfs(int x){ vis[x]=true; dp[x][0]=0; dp[x][1]=w[x]; for (int i=adj[x];i;i=bian[i].next){ int v=bian[i].v; if(!vis[v]){ dfs(v); dp[x][0]+=max(dp[v][1],dp[v][0]); dp[x][1]+=dp[v][0]; } } } int main(){ int u,v; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&w[i]); while(scanf("%d%d",&u,&v)&&u){ myinsert(u,v); myinsert(v,u); vis[u]=1; } int root=0; for (int i=1;i<=n;i++) if(!vis[i]) { root=i; break; } memset(vis,0,sizeof(vis)); dfs(root); printf("%d ",max(dp[root][1],dp[root][0])); return 0; }