标签:include scanf tput key wan ret everyone title content
传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=1520
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 16376 Accepted Submission(s): 6241
#include <iostream> #include <stdio.h> #include<memory> #include<stack> #include<string.h> #include<algorithm> using namespace std; #define max_v 6005 struct node { int pa,son; int next; } point[max_v]; int dp[max_v][2]; //dp[i][1]表示第i个参与者参加了,dp[i][0]表示第i个参与者没有参加 //状态转移方程就: //dp[i][1]=dp[i][1]+dp[i-1][0] //dp[i][0]=dp[i][0]+Max(dp[i-1][0],dp[i-1][1]) int List[max_v]; int vis[max_v];//vis[a]=1 表示a有父节点 int value[max_v];//存值 int pos; void add(int pa,int son) { point[pos].pa=pa; point[pos].son=son; point[pos].next=List[pa]; List[pa]=pos++; } void dfs(int root) { if(List[root]==-1)//root没有子节点了 { dp[root][1]=value[root]; dp[root][0]=0; return ; } int now=List[root]; dp[root][0]=0; dp[root][1]=value[root]; while(now!=-1) { dfs(point[now].son); dp[root][1]+=dp[point[now].son][0];//既然取了父节点的值,子节点的值就不能再取了。 //父节点的值没有取,子节点的值分取和不取两种情况,取其中较大的那种情况。 dp[root][0]+=max(dp[point[now].son][1],dp[point[now].son][0]); now=point[now].next;//这个子节点计算过了,就要开始计算下一个子节点了 } return ; } int main() { int n; while(cin>>n) { for(int i=1; i<=n; i++) cin>>value[i];//记录每一个点的值 memset(List,-1,sizeof(List)); memset(vis,0,sizeof(vis)); int a,b; pos=0; while(~scanf("%d %d",&a,&b)) { if(a==0&&b==0) break; add(b,a); //将边加入树中 vis[a]=1; //记录a有父节点,不可能是祖节点。 } a=1; while(vis[a]==1) a++;//找到根结点 dfs(a);//从根结点开始搜 printf("%d\n",max(dp[a][0],dp[a][1]));//取最大 } return 0; }
hdu 1520 Anniversary party(第一道树形dp)
标签:include scanf tput key wan ret everyone title content
原文地址:https://www.cnblogs.com/yinbiao/p/9406533.html