http://acm.hdu.edu.cn/showproblem.php?pid=1520
题意: 一个大学要举行职工party。为使party中每个人都玩的开心,直接上司和下属关系的员工不能同时参加。每个人都有各自的欢乐值。
问如何邀请使得总欢乐值最大。
dp[i][1] 表示选择i点 dp[i][0]表示不选择i点
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 6005;
int n;
int w[maxn],dp[maxn][2];
bool vis[maxn];
vector<int>tree[maxn];
int Max( int a,int b )
{
return a>=b?a:b;
}
void dfs( int u )
{
vis[u] = true;
dp[u][1] = w[u];
for( int i = 0; i < tree[u].size(); i ++ )
{
int v = tree[u][i];
if( !vis[v] )
{
dfs( v );
dp[u][1] += dp[v][0];
dp[u][0] += Max( dp[v][0],dp[v][1] );
}
}
}
void init()
{
memset(vis,0,sizeof(vis));
memset(dp,0,sizeof(dp));
for( int i = 1; i <= n; i ++ )
{
tree[i].clear();
}
}
int main()
{
int a,b;
while( scanf("%d",&n) != EOF )
{
init();
for( int i = 1; i <= n; i ++ )
{
scanf("%d",&w[i]);
}
while( scanf("%d%d",&a,&b),a+b )
{
tree[a].push_back(b);
tree[b].push_back(a);
}
dfs(1); //由于建的是无向图,可以任意找个点当树根进行DP 但是在搜索中要判重,加个vis数组
printf("%d\n",Max( dp[1][0], dp[1][1] ) );
}
return 0;
}