标签:最大独立集
题目链接:点击打开链接
题目描述:现有一棵树,树上每个结点都有一个权值,问从中选一些点,这些点两两之间不直接连接,问权值最大为多少?
解题思路:很裸的一道树上最大独立集问题 树形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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu1520 Anniversary party(最大独立集 树形dp)
标签:最大独立集
原文地址:http://blog.csdn.net/mengxingyuanlove/article/details/48000255