首页 > 代码库 > 树的最大独立集
树的最大独立集
p280 9.4.2
原问题d(i)是以i为根节点,子问题是以i的儿子节点和以i的孙子节点为根节点。
讲解中的“当计算出一个d(i)后,用它去更新i的父亲和祖父节点的累加值”,对应到代码,需要从树的叶子节点开始计算d(i),可以用dfs
下面是 poj 2342的代码,例题9-13 UVa 1220 对应 poj 3342
#define _CRT_SECURE_NO_WARNINGS#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<vector>#include<algorithm>using namespace std;int N;// 1 <= N <= 6000;const int maxn = 6000;// d[u][0]表示当不选前节点u,能获得的最大conviviality rating// d[u][1]表示当选择前结点u,能获得的最大conviviality ratingint d[maxn + 5][2];int visit[maxn + 5][2]; // d[u][k] already calculated// the supervisor relation forms a treeint parent[maxn + 5];int root;vector<int> sons[maxn + 5]; // sons of a parent// d[u][k], k==1 or k==0// depth first searchint dp(int u, int k) { if (visit[u][k] > 0) return d[u][k]; if (k == 0) d[u][0] = 0; for (int j = 0; j < sons[u].size(); j++) { // for each son of vertex u int v = sons[u][j]; if (k == 1) { // select u, not select v d[u][1] += dp(v,0); // dfs } else { // not select u, select or not select v d[u][0] += max(dp(v, 1), dp(v, 0)); // dfs } } visit[u][k] = 1; return d[u][k];}int main(){ while (scanf("%d", &N) != EOF){ memset(d, 0, sizeof(d)); memset(visit, 0, sizeof(visit)); memset(parent, 0, sizeof(parent)); for (int i = 1; i <= N; i++) sons[i].clear(); for (int i = 1; i <= N; i++) scanf("%d", &d[i][1]); for (int i = 1; i <= N; i++){ int L, K; scanf("%d%d", &L, &K); if (L == 0 && K == 0) // end of input break; parent[L] = K; sons[K].push_back(L); } for (int i = 1; i <= N; i++){ if (parent[i] == 0){ root = i; break; } } printf("%d\n", max(dp(root, 0), dp(root, 1))); } return 0;}
树的最大独立集
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。