poj 1463 树形dp入门

很简单的树形dp题目,转移方程是:

dp[u][0] += dp[v][1];
     dp[u][1] += min( dp[v][0], dp[v][1] );

其中u是v的父亲节点。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6
 7 const int N = 1500;
 8 bool flag[N];
 9 int head[N];
10 int dp[N][2];
11 int e, n;
12
13 void init()
14 {
15     e = 0;
16     memset( flag, true, sizeof(flag) );
17     memset( head, -1, sizeof(head) );
18 }
19
20 struct Edge
21 {
22     int v, next;
23 } edge[N];
24
25 void addEdge( int u, int v )
26 {
27     edge[e].v = v;
28     edge[e].next = head[u];
29     head[u] = e++;
30 }
31
32 void dfs( int u )
33 {
34     dp[u][0] = 0;
35     dp[u][1] = 1;
36     for ( int i = head[u]; i != -1; i = edge[i].next )
37     {
38         int v = edge[i].v;
39         dfs(v);
40         dp[u][0] += dp[v][1];
41         dp[u][1] += min( dp[v][0], dp[v][1] );
42     }
43 }
44
45 int main ()
46 {
47     while ( scanf("%d", &n) != EOF )
48     {
49         init();
50         for ( int i = 0; i < n; i++ )
51         {
52             int u, v, m;
53             scanf("%d:(%d)", &u, &m);
54             while ( m-- )
55             {
56                 scanf("%d", &v);
57                 addEdge( u, v );
58                 flag[v] = false;
59             }
60         }
61         int root;
62         for ( int i = 0; i < n; i++ )
63         {
64             if ( flag[i] )
65             {
66                 root = i;
67                 break;
68             }
69         }
70         dfs(root);
71         int ans = min( dp[root][0], dp[root][1] );
72         printf("%d\n", ans);
73     }
74     return 0;
75 }

也可以用二分图来做。

时间: 2024-10-08 10:30:56

poj 1463 树形dp入门的相关文章

POJ 3342 树形DP入门题

题目意思和POJ2342一样,只是多加了一个条件,如果最大方案数唯一,输出Yes,不唯一输出No dp的是时候多加一个变量记录答案是否唯一即可 #include "stdio.h" #include "string.h" #include "vector" using namespace std; struct node { int fa; vector<int>child; }data[210]; struct comp { int

POJ 1947 树形DP入门题

给出N个点,N-1个关系,建出树形图,问最少减去几个边能得到节点数为P的树.典型树形DP题 dp[cur][j] :记录cur结点,要得到一棵j个节点的子树去掉的最少边数 转移方程用的背包的思想 对当前树的每一个子树进行计算 砍掉此子树:   dp[cur][j]=dp[cur][j]+1; 不砍掉:           for (l=0;l<=j;l++)  dp[cur][j]=Min(dp[cur][j],dp[cur][l]+dp[next][j-l]); 枚举从该树中留l个节点其他由新

POJ 2342 树形DP入门题

有一个大学的庆典晚会,想邀请一些在大学任职的人来参加,每个人有自己的搞笑值,但是现在遇到一个问题就是如果两个人之间有直接的上下级关系,那么他们中只能有一个来参加,求请来一部分人之后,搞笑值的最大是多少. 树形DP入门题. DP部分: dp[i][0]表示职员i不来参加party,以i为根的子树的最大搞笑值, dp[i][1]表示职员i来参加party,以i为根的子树的最大搞笑值. 转移方程: dp[cur][1]+=dp[next][0]; dp[cur][0]+=Max(dp[next][1]

poj 1463(树形DP)

Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 7584   Accepted: 3518 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad

Strategic game(POJ 1463 树形DP)

Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 7490   Accepted: 3483 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad

poj 1463树形dp 树的最小覆盖

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> using namespace std; // push_back inline int read(){ int sum=0,x=1; char ch=getchar(); while(ch<'0'||ch>'9

树形dp入门之poj 2342

题目:poj2342Anniversary party 题意:话说一个公司的一些然要去参加一个party,每个人有一个愉悦值,而如果某个人的直接上司在场的话会非常扫兴,所以避免这样的安排,问给出n个人,每个人的愉悦值以及他们的上司所属关系,问你让那些人去可以让总的愉悦值最大,并求出这个值. 分析:树形dp入门题目,这个公司的人事关系可以根据给出的数据得到一个树,最上面的是最高层,往下依次,我们要做的就是在树的节点处进行dp. 用dp[i][0]表示当前i这个人不选,dp[i][1]表示当前i这个

poj 3342(树形dp)

题意:在一个公司中要举办一个聚会,每一个员工有一个奉献值.为了和谐规定直接上下级不能一起出席.让你找出奉献值之和最大为多少. 思路:dp[v][1]表示当前结点选,能获得的最大奉献值,dp[v][0]表示当前节点不选能获得的最大奉献值.状态转移: dp[v][0] = max(dp[v][0], ∑max(dp[x][1], dp[x][0]))x为直接儿子 dp[v][1] = max(dp[v][1], ∑dp[x][0] + vex[v]) 最后答案是max(dp[root][0], dp

[poj2342]Anniversary party树形dp入门

题意:选出不含直接上下司关系的最大价值. 解题关键:树形dp入门题,注意怎么找出根节点,运用了并查集的思想. 转移方程:dp[i][1]+=dp[j][0];/i是j的子树 dp[i][0]+=max(dp[j][0],dp[j][1]); 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6