树形DP <简单树形DP 对我来说重点在建树> hlg 1474
2012-07-19 22:56
411 查看
受挫了..
主要是题做的还太少了..而且我基础不踏实..建树都建不好..
加油吧~
题意:
给出 n 个节点和 m 个关系..
保证是一棵树..父子节点不能同时出现..根节点一定要有..求节点出现最多值..
思路:
叶节点的值是可以肯定的..从下往上DP就好..
对我来说难点还是不会建树..
Tips:
初始条件: dp[ leaf ][ 0 ] = 0, dp[ leaf ][ 1 ] = 1;
动态转移方程 :
dp[r][1] += dp[tmp][0];
dp[r][0] += max(dp[tmp][1], dp[tmp][0]);
结果: dp[ root ][1]
L_Squirrel:
用vector 方便建树..
用visited来标记..然后遍历可以找到根节点..
Code:
链表建树:
struct node
{
int v,next;
}edge[ ];
void add(int u,int v)
{
edge[tol].v=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void dfs(int x)
{
dp[x][1]=1;
dp[x][0]=0;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int t=edge[i].v;
dfs(t);
dp[x][0]+=max(dp[t][1],dp[t][0]);
dp[x][1]+=dp[t][0];
}
}
主要是题做的还太少了..而且我基础不踏实..建树都建不好..
加油吧~
题意:
给出 n 个节点和 m 个关系..
保证是一棵树..父子节点不能同时出现..根节点一定要有..求节点出现最多值..
思路:
叶节点的值是可以肯定的..从下往上DP就好..
对我来说难点还是不会建树..
Tips:
初始条件: dp[ leaf ][ 0 ] = 0, dp[ leaf ][ 1 ] = 1;
动态转移方程 :
dp[r][1] += dp[tmp][0];
dp[r][0] += max(dp[tmp][1], dp[tmp][0]);
结果: dp[ root ][1]
L_Squirrel:
用vector 方便建树..
用visited来标记..然后遍历可以找到根节点..
Code:
#include <stdio.h> #include <cstring> #include <fstream> #include <vector> using namespace std; vector<int> con[2010]; bool visited[2010]; int dp[2010][2]; void dfs(int r) { dp[r][0] = 0; dp[r][1] = 1; int len = con[r].size(); for(int i = 0; i < len; ++i){ int tmp = con[r][i]; dfs(tmp); dp[r][1] += dp[tmp][0]; dp[r][0] += max(dp[tmp][1], dp[tmp][0]); } } int main() { int i, j, k; int n, m; int a, b; // freopen("e:\\acm\\mess\\stdin-stdout\\in_c.txt", "r", stdin); // freopen("e:\\acm\\mess\\stdin-stdout\\out_c.txt", "w", stdout); while(scanf("%d %d", &n, &m) != EOF) { memset(visited, false, sizeof(visited)); memset(dp, 0, sizeof(dp)); for(i = 0; i <= n; ++i) con[i].clear(); for(i = 1; i <= m; ++i){ scanf("%d %d", &a, &b); con[a].push_back(b); visited[b] = true; } for(i = 1; i <= n; ++i) if(!visited[i]) break; int root = i; dfs(root); printf("%d\n", dp[root][1]); } return 0; }
链表建树:
struct node
{
int v,next;
}edge[ ];
void add(int u,int v)
{
edge[tol].v=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void dfs(int x)
{
dp[x][1]=1;
dp[x][0]=0;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int t=edge[i].v;
dfs(t);
dp[x][0]+=max(dp[t][1],dp[t][0]);
dp[x][1]+=dp[t][0];
}
}
相关文章推荐
- DP【状态压缩 】 <简单?> hlg 1473
- 树形DP <dfs+floyd> 【hlg】 1329 游乐园
- <Java Web学习初级阶段>JavaScript实现简单网页计算器
- C# List<>简单用法
- LeetCode121/122/123/188 Best Time to Buy and Sell Stock<股票> I/II/III/IIII----DP+Greedy**
- 如何使用CSS设置<input>标签的背景小图标 简单
- hdu1561--树形dp<依赖背包>
- 导弹拦截<DP><贪心><C++>
- 实现一个快速简单的SimpleListDialog<T>
- c++ primer(第五版)笔记 第十三章(4) string 类和 vector<string> 容器的简单实现
- 简单的单链表<实现单链表的增删查改逆序和寻找中间节点>
- Android实战简易教程<十一>(树形组件:ExpandableListView显示和动态添加删除)
- C#_delegate - Pair<T> & 简单顺序逆序 & 方法委托(在Pair类下)&枚举类型 混搭使用
- <一>读<<大话设计模式>>之简单工厂模式
- hdu--4576--概率dp<见过最简单的概率dp>
- (vijos 1892 noip 模拟 tree)<树形DP求树的最大匹配及方案数>
- Android0910<十五>(简单的音乐播放器)
- struts2通过<s:tree>或者dtree插件 建立树形结构
- java_web初学笔记之<Tomcat服务器的简单配置>
- Android Netroid框架介绍及使用,又一简单粗暴的网络框架!<Garry进阶(二)>