题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520
Anniversary party
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12366 Accepted Submission(s): 5009
L K
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line
0 0
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
5
题解:
dp[u][state]:结点u其状态为state(0或1,即不放和放)的最大值。
状态转移:
1.如果当前结点不放,那么它的子结点放不放都行,所以两者取其大。
2.如果当前结点放,那么它的子节点只能不放。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+7;
const int MAXN = 1e4+10;
int val[MAXN], hav_fa[MAXN], dp[MAXN][2];
vector<int>son[MAXN];
int dfs(int u)
{
dp[u][0] = 0; //不放,初始化为0
dp[u][1] = val[u]; //放,初始化为本身的值
for(int i = 0; i<son[u].size(); i++)
{
int v = son[u][i];
dfs(v); //递归其子树
dp[u][0] += max(dp[v][0], dp[v][1]); //如果不放,那么它的子节点放不放都行,所以取其大。
dp[u][1] += dp[v][0]; //如果放,那么它的子节点不能放
}
return max(dp[u][0], dp[u][1]); //返回最大值
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i = 1; i<=n; i++)
son[i].clear(), hav_fa[i] = 0;
for(int i = 1; i<=n; i++)
scanf("%d",&val[i]);
int u, v;
while(scanf("%d%d",&v,&u) && (v || u))
{
son[u].push_back(v);
hav_fa[v] = 1;
}
for(int i = 1; i<=n; i++) //找到根节点,然后深搜
if(!hav_fa[i])
cout<< dfs(i) <<endl;
}
}
304



被折叠的 条评论
为什么被折叠?



