hdu 2196 Computer(树形DP,两次dfs)好好看。。。
来源:互联网 发布:淘宝二手市场怎么买卖 编辑:程序博客网 时间:2024/06/05 18:15
1、http://acm.hdu.edu.cn/showproblem.php?pid=2196
2、题目大意:(参考http://blog.csdn.net/shuangde800/article/details/9732825)
给出一棵树,求每一个结点到其他结点的最远权值和,
对于结点u来说,他的最大权值和可能来自两个方向,一个是u作为根节点到其子节点的最大值,另一个是以u的父节点为根的树的最大权值和加上根节点到u的距离
假设存在这么一棵树
1
2 3
4 5 6
7
1是根节点,23是1的孩子,45是2的孩子,6是3的孩子,7是6的孩子
我们假设要求2的最大距离值,有两种状态,
1、2作为根节点,到其孩子的最大距离值
2、2作为选中的路径的子节点,选中的子树以2的父节点1为根节点的子树,我们可以看到以1为根节点的子树的最大值再加上1-2的距离就是所求,但是前提是选中的1结点为根的最大值的子树中不包含2,假设包含2这个结点,那么最大值就是以2为根的,
adj(v-u)表示v-u之间的距离
dp[v][2]=max(dp[u][2],dp[v][0]+adj(v-u)==dp[u][0]?dp[u][1]:dp[u][0])+adj(v-u)
dp[v][0]表示以v为根节点的子树的最大值
dp[v][1]表示以v为根节点的子树的次大值(第二大)
3、超时代码:
#include<stdio.h>#define N 10005#include<vector>#include<algorithm>using namespace std;int dp[N][3];struct node{ int v; int w;};vector<node> adj[N];void dfs1(int u){ //printf("*****%d\n",adj[u].size()); int biggest=0,bigger=0; for(int i=0;i<adj[u].size();i++) { int vv=adj[u][i].v; dfs1(vv); int tmp=dp[vv][0]+adj[u][i].w; //printf("***%d %d\n",dp[vv][0],adj[u][i].w); if(tmp>=biggest) { bigger=biggest; biggest=tmp; } else if(tmp>bigger) { bigger=tmp; } } dp[u][0]=biggest; dp[u][1]=bigger;}void dfs2(int u){ for(int i=0;i<adj[u].size();i++) { int vv=adj[u][i].v; dp[vv][2]=max(dp[u][2],dp[u][0]==dp[vv][0]+adj[u][i].w?dp[u][1]:dp[u][0])+adj[u][i].w; dfs2(vv); }}int main(){ int n,a,b; while(scanf("%d",&n)!=EOF) { for(int i=2;i<=n;i++) { scanf("%d%d",&a,&b); node tmp; tmp.v=i; tmp.w=b; adj[a].push_back(tmp); } dfs1(1); dp[1][2]=0; dfs2(1); for(int i=1;i<=n;i++) printf("%d\n",max(dp[i][0],dp[i][2])); } return 0;}
4、AC代码:
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 1e4 + 5;struct Vertex{ int head;} V[N];struct Edge{ int v,w,next;} E[N];int top;void init(){ memset(V,-1,sizeof(V)); top = 0;}void add_edge(int u,int v,int w){ E[top].v = v; E[top].w = w; E[top].next = V[u].head; V[u].head = top++;}int dp[N][3];void dfs1(int u){ int biggest = 0 , bigger = 0; for(int i=V[u].head; ~i; i=E[i].next) { int v = E[i].v; dfs1(v); int tmp = dp[v][0]+E[i].w; if(biggest <= tmp) { bigger = biggest; biggest = tmp; } else if(bigger < tmp) bigger = tmp; } dp[u][0] = biggest; dp[u][1] = bigger;}void dfs2(int u){ for(int i=V[u].head; ~i; i=E[i].next) { int v = E[i].v; dp[v][2] = max(dp[u][2] , dp[v][0]+E[i].w==dp[u][0] ? dp[u][1] : dp[u][0]) + E[i].w; dfs2(v); }}int main(){ int n; while(~scanf("%d",&n)) { init(); for(int v=2; v<=n; v++) { int u,w; scanf("%d%d",&u,&w); add_edge(u,v,w); } dfs1(1); dp[1][2] = 0; dfs2(1); for(int i=1; i<=n; i++) printf("%d\n",max(dp[i][0],dp[i][2])); } return 0;}
0 0
- hdu 2196 Computer(树形DP,两次dfs)好好看。。。
- hdu 2196 Computer (树形dp+两次dfs遍历)
- HDU 2196 Computer 树形DP+dfs预处理
- hdu 2196 Computer dfs / 树形dp
- hdu 2196 Computer 树形DP 求每个点的最远点距离 两次dfs的经典树形dp
- hdu 2196 Computer(树dp+两次dfs)
- HDU 2196 Computer 树形DP(2个dfs)
- HDU 2196 Computer(树形dp)
- 【树形DP】 HDU 2196 Computer
- HDU 2196 Computer(树形DP)
- Hdu 2196 Computer(树形dp)
- Computer - HDU 2196 树形dp
- Hdu 2196 Computer (树形dp)
- HDU 2196 Computer | 树形dp
- 【树形DP】 HDU 2196 Computer
- HDU 2196 Computer (树形DP)
- hdu 2196 Computer (树形dp)
- *HDU 2196 - Computer(树形DP)
- 电子商务杨煜:利用IM工具进行产品营销活动设计
- 【慎思堂】之议家长里短:Javascript与JQuery
- QT SQL使用指南
- C++static 数据成员
- Serializable 接口–java.io.serializable
- hdu 2196 Computer(树形DP,两次dfs)好好看。。。
- 矩阵论 第一章 基础概念和定律
- Balanced Binary Tree
- 近两年的状态,以及近期的一些想法
- js中apply方法的使用
- 三.char 与 unsigned char的本质区别
- TeeChart经验总结——使用Axis
- 球面细分(下)
- Reverse Integer