您的位置:首页 > 其它

hdu1520 Anniversary party(最大独立集 树形dp)

2015-08-26 10:57 197 查看
题目链接:点击打开链接

题目描述:现有一棵树,树上每个结点都有一个权值,问从中选一些点,这些点两两之间不直接连接,问权值最大为多少?

解题思路:很裸的一道树上最大独立集问题 树形dp即可

dp[i][0]:不选i节点 dp[i][0]+=max(dp[t][0],dp[t][1]);

dp[i][1]:选i节点 dp[i][1]+=dp[t][0];

代码:

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 6010
using namespace std;
int head[MAXN],tol;
struct Edge{
int v,next;
}edge[MAXN];
void addEdge(int u,int v){
edge[tol].v=v;edge[tol].next=head[u];head[u]=tol++;
}
int max(int a,int b){
return a>b?a:b;
}
int dp[MAXN][2];
int n,value[MAXN];
bool vis[MAXN];
void DP(int u,int p){
dp[u][0]=0;
dp[u][1]=value[u];
int k,to;
for(k=head[u];k!=-1;k=edge[k].next){
to=edge[k].v;
if(to==p) continue;
DP(to,u);
dp[u][0]+=max(dp[to][0],dp[to][1]);
dp[u][1]+=dp[to][0];
}
}
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;++i) scanf("%d",&value[i]);
int u,v;
tol=0;memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
while(scanf("%d%d",&u,&v)!=EOF&&(u!=0||v!=0)) {addEdge(v,u);vis[u]=true;}
int root;
for(int i=1;i<=n;i++){if(!vis[i]) {root=i;break;}}
DP(root,root);
printf("%d\n",max(dp[root][0],dp[root][1]));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: