您的位置:首页 > 大数据 > 人工智能

2014taichuan D题

2015-10-14 14:41 537 查看
题意:给定一颗有N个节点的树,一开始每个节点都是白色的,现在要对每个节点进行决策,使得每个白色节点连接着恰好K个黑色节点,如果达不到则这个白色节点变为黑色

分析:树形dp 

g[u] 表示以u为根节点的子树且u节点为黑色时的最大白点数

f[u][i] 表示以u为根节点时的子树且u为白色节点时连接i个黑色节点的最大白点数,这里的转移是一个树上的背包

#include

const int N = 100 + 5;

int n, m;
char buffer[1000 + 5];
int g
, f
[10 + 5];
std::vector  edges
;

void dfs(int u) {
g[u] = 0;
f[u][0] = 1;
for (int i = 1; i <= m; i ++) {
f[u][i] = -1;
}
for (int i = 0; i < (int)edges[u].size(); i ++) {
int v = edges[u][i];
dfs(v);
g[u] += std::max(g[v], f[v][m - 1]);
for (int j = m; j >= 0; j --) {
f[u][j] = f[u][j] + f[v][m];
if (j) {
f[u][j] = std::max(f[u][j], f[u][j - 1] + g[v]);
}
}
}
}

int work() {
if (m == 0) {
return n;
}
dfs(0);
return std::max(g[0], f[0][m]);
}

int main() {
int t;
scanf("%d", &t);
while (t --) {
scanf("%d%d", &n, &m);
getchar();
for (int i = 0; i < n; i ++) {
edges[i].clear();
gets(buffer);
std::istringstream is(buffer);
int x;
while (is >> x && x) {
edges[i].push_back(x - 1);
}
}
printf("%d\n", work());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: