poj 1463-树形dp
这道题是我的第一道树形dp,也是最简单的一道树形dp-背包问题,每个点只是考虑选与不选的问题,基本上和0-1背包是一模一样的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h>
2 #include<string.h>
3 #define MAX 1501
4 int pre[MAX],child[MAX];//父节点和儿子节点
5 int dp[MAX][2];//0表示不选,1表示选
6 int min(int a,int b)
7 {
8 return a<b?a:b;
9 }
10 int n;
11 int used[MAX];
12 void fun(int r)
13 {
14 used[r]=1;
15 int i;
16 if(child[r]==0)
17 {
18 dp[r][1]=1;
19 dp[r][0]=0;
20 return;
21 }
22 int m=child[r];
23 int dp0=0;
24 int dp1=0;
25 for(i=0;i<n;i++)
26 {
27 if(pre[i]==r)
28 {
29 if(!used[i])
30 {
31 fun(i);
32 }
33 dp1+=min(dp[i][1],dp[i][0]);
34 dp0+=dp[i][1];
35 }
36 }
37 dp[r][1]=dp1+1;
38 dp[r][0]=dp0;
39 }
40 int main()
41 {
42 int i,nroot,root,m,cld;
43 while(scanf("%d",&n)!=EOF)
44 {
45 memset(pre,-1,sizeof(pre));
46 memset(child,-1,sizeof(child));
47 memset(dp,0,sizeof(dp));
48 memset(used,0,sizeof(used));
49 for(i=0;i<n;i++)
50 {
51 scanf("%d:(%d)",&nroot,&m);
52 if(!i)
53 root=nroot;
54 child[nroot]=m;
55 while(m--)
56 {
57 scanf("%d",&cld);
58 pre[cld]=nroot;
59 if(cld==root)
60 root=nroot;
61 }
62 }
63 fun(root);
64 printf("%d\n",min(dp[root][1],dp[root][0]));
65 }
66 return 0;
67 }