问题描述:公司办晚会,每个人都有一个活跃度,为了气氛好,要求不能同时把上司和员工分在一起(约束条件)。让你去做出选择,尽力让总活跃度最大。很明显一个动态规划问题。
Sample Input
7
1 //可以画棵树
1
1
1
1
1
1
1 3 //L K,K是L的上司 3是1的上司
2 3
6 4
7 4
4 5
3 5
0 0
<img data-cke-saved-src="https://img-blog.csdn.net/20180201141114462?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGlwaXRvbmdrdzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" src="https://img-blog.csdn.net/20180201141114462?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGlwaXRvbmdrdzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
Sample Output
5
题目来源:http://poj.org/problem?id=2342
思路是:深搜便利该树,已访问过的结点不再访问。
代码来源: http://blog.csdn.net/sr_19930829/article/details/40537507
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=6005;
vector<int>son[maxn]; //???
bool vis[maxn];
int dp[maxn][2];
int n;
void dfs(int root)
{
vis[root]=1;
for(int i=0;i<son[root].size();i++) //son[root].size()是son的子节点总个数吗
{
int v=son[root][i];
if(!vis[v])
{
dfs(v);
dp[root][1]+=dp[v][0];
dp[root][0]+=max(dp[v][0],dp[v][1]);
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<=n;i++)
son[i].clear(); //
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
scanf("%d",&dp[i][1]);
dp[i][0]=0;
}
int fa,so;
while(scanf("%d%d",&so,&fa)!=EOF)
{
if(so==0&&fa==0)
break;
son[fa].push_back(so);
son[so].push_back(fa);
}
dfs(1);
cout<<max(dp[1][0],dp[1][1])<<endl;
}
return 0;
}