HDU_2196 树形DP
来源:互联网 发布:淘宝嘉年华日期 编辑:程序博客网 时间:2024/05/30 23:47
题目的大意是:有一棵N个节点的树(N<10000),树的每一条边都有一个边权,求这棵树上每个节点的最长链长。
用树形dp来写,dp[i]代表第i个节点的最长链的长度,dp1[i]代表第i个节点在其和其子树上的最长链的长度,dp3[[i]代表第i个节点向上的最长链的长度,这样我们写出转移方程:
dp[i] = max(dp1[i],dp3[i])。
dp1[i]我们只需要一次最简单的dfs从根(1)遍历到叶子节点就好了,dp3[i]要怎么求?dp3[i]代表第i个节点往上的最长链,我们在往上找i的根节点fa[i],不妨叫做fa。那么dp3[i]的的值就是dp3[fa]和fa节点往下(除了i节点以外的子树的最长链),这个时候我们就需要一个dp2[i]代表第i个节点及其子树的第二长链。这样我们得到dp3[i]的转移方程;
dp3[i] = max{dp3[fa],g[fa][i]+dp1[i] == dp1[fa] ? dp2[fa]:dp1[fa]}+g[fa][i]。其中g[fa][i]代表的是边的权值:
这样我们在用一个dfs来遍历得到所有的dp3[i],dp2[i]可以再得到dp1[i]是得到,下面是ac代码:
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <vector>#define ll long long#define FOR(i,x,y) for(int i = x;i < y;i ++)#define INF 1<<31using namespace std;const int MAXN = 11111;int dp1[MAXN],dp2[MAXN],dp3[MAXN],dp[MAXN];int N;vector <pair<int,int> > G[MAXN];
//得到dp1[i],dp2[i]
int dfs1(int u,int fa){ dp1[u] = 0; dp2[u] = 0; int tem[MAXN],tem_cnt = 0; vector <pair<int,int> > :: iterator it; for(it = G[u].begin();it != G[u].end();it ++){ int v = it->first,val = it->second; if(v == fa) continue; tem[tem_cnt++] = val+dfs1(v,u); } sort(tem,tem+tem_cnt); if(tem_cnt >= 2){ dp1[u] = tem[tem_cnt-1]; dp2[u] = tem[tem_cnt-2]; } else if(tem_cnt == 1) dp1[u] =tem[tem_cnt-1]; return dp1[u];}
//求出所有dp3[i],其实这里就可以求出dp[i]了void dfs3(int u,int fa){ vector <pair<int,int> > :: iterator it; for(it = G[u].begin();it != G[u].end();it ++){ int v = it->first,val = it->second; if(v == fa) continue; if(dp1[u] == dp1[v]+val) dp3[v] = max(dp2[u],dp3[u]) + val; else dp3[v] = max(dp1[u],dp3[u]) + val; dfs3(v,u); }}int main(){ //freopen("test.in","r",stdin); while(~scanf("%d",&N)){ FOR(i,1,N+1) G[i].clear(); int to,val; //val代表的是编的权值 FOR(i,2,N+1){ scanf("%d%d",&to,&val); G[i].push_back(make_pair(to,val)); G[to].push_back(make_pair(i,val)); } dfs1(1,-1); dp3[1] = 0; dfs3(1,-1); FOR(i,1,N+1) dp[i] = max(dp1[i],dp3[i]); FOR(i,1,N+1) printf("%d\n",dp[i]); } return 0;}
0 0
- HDU_2196 树形DP
- hdu_2196 computer 树状dp经典入门题
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 树形DP
- 树形dp
- 树形dp
- 树形dp
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 用有数据的单元格内容向下填充空白单元格
- servlet图解。1。。tomcat处理请求过程、servlet的生命周期
- struts.enable.SlashesInActionNames 无效
- 8大排序算法图文讲解
- 递归删除空目录
- HDU_2196 树形DP
- flexibility of openstack(3)
- Median of Two Sorted Arrays
- 下次我要一个人创业
- 高效程序员的45个习惯之敏捷编码
- Django学习笔记(第二节)Hello World站点
- 数论-唯一分解定理
- 第九周项目2(1)-Time类中的运算符重载(续)
- 结构体类型数据作为函数参数(三种方法