问题描述
有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?
数据规模与约定
对于20%的数据, n <= 20。
对于50%的数据, n <= 1000。
对于100%的数据, n <= 1e5。
权值均为不超过1000的正整数
思路:
一开始想着就一个简单的二维数组去建树判断,但是提交上去发现运行错误,数组开太大,空间不够。
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e5;
int a[maxn];
int vis[maxn];
int tree[maxn][maxn];
int n,max_,d,b,c;
void dp(int tot, int sum, int x)
{
if(tot == 3)
{
if(max_ < sum)
max_ = sum;
return ;
}
for(int j=1; j<=n; j++)
{
if(x != j && tree[x][j] != 1 && !vis[j])
{
vis[j] = 1;
dp(tot+1,sum+a[j],j);
vis[j] = 0;
}
}
}
int main()
{
while(cin >> n)
{
max_ = 0;
for(int i=0; i<=n; i++)
memset(tree[i], 0 , n);
for(int i=1; i<=n; i++)
{
cin >> a[i];
}
for(int i=0; i<n-1; i++)
{
int l,r;
cin >> l >> r;
tree[l][r] = tree[r][l] = 1;
}
for(int i=1; i<=n; i++)
{
memset(vis, 0 , sizeof vis);
vis[i] = 1;
dp(1,a[i],i);
}
cout << max_ << endl;
}
return 0;
}
参考了一下网上的:
采用《孩子表示法》的树状存储,不用二维,而用结构体。