HDU-2196 Computer (树形DP)

题目大意:在一棵带边权的有根树中,对于每个点,找出它与离它最远的那个点的之间的距离。

题目分析:对于一个点,离它最远的点只有两种情况,一是它到叶子节点的最远距离,一是与它父亲的距离加上他的父亲到叶子节点的最远距离。因为它的父亲到叶子的最远距离的那条路径可能恰好经过它自己,所以还要求出每个点到叶子节点的次大距离。

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;

const int N=10010;

struct Edge
{
	int to,w,nxt;
};
Edge e[N*2];
int n,cnt;
int head[N];
int maxn[N];
int smaxn[N];
int maxid[N];
int smaxid[N];

void init()
{
	cnt=0;
	memset(head,-1,sizeof(head));
}

void add(int u,int v,int w)
{
	e[cnt].to=v;
	e[cnt].w=w;
	e[cnt].nxt=head[u];
	head[u]=cnt++;
}

void read()
{
	int a,b;
	for(int i=2;i<=n;++i){
		scanf("%d%d",&a,&b);
		add(i,a,b);
		add(a,i,b);
	}
}

void dfs1(int u,int fa)
{
	maxn[u]=smaxn[u]=0;
	for(int i=head[u];i!=-1;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa) continue;
		dfs1(v,u);
		if(e[i].w+maxn[v]>smaxn[u]){
			smaxn[u]=e[i].w+maxn[v];
			smaxid[u]=v;
			if(smaxn[u]>maxn[u]){
				swap(smaxn[u],maxn[u]);
				swap(smaxid[u],maxid[u]);
			}
		}
	}
}

void dfs2(int u,int fa)
{
	for(int i=head[u];i!=-1;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa)continue;
		if(v==maxid[u]){
			if(e[i].w+smaxn[u]>smaxn[v]){
				smaxn[v]=e[i].w+smaxn[u];
				smaxid[v]=u;
				if(smaxn[v]>maxn[v]){
					swap(smaxn[v],maxn[v]);
					swap(smaxid[v],maxid[v]);
				}
			}
		}else{
			if(e[i].w+maxn[u]>smaxn[v]){
				smaxn[v]=e[i].w+maxn[u];
				smaxid[v]=u;
				if(smaxn[v]>maxn[v]){
					swap(smaxn[v],maxn[v]);
					swap(smaxid[v],maxid[v]);
				}
			}
		}
		dfs2(v,u);
	}
}

void solve()
{
	dfs1(1,-1);
	dfs2(1,-1);
	for(int i=1;i<=n;++i)
		printf("%d\n",maxn[i]);
}

int main()
{
	while(~scanf("%d",&n))
	{
		init();
		read();
		solve();
	}
	return 0;
}

  

时间: 2024-08-10 02:09:59

HDU-2196 Computer (树形DP)的相关文章

HDU 2196 Computer 树形DP经典题

链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问每台电脑和其它电脑的最远距离是多少. 思路:这是一道树形DP的经典题目.须要两次DFS,第一次DFS找到树上全部的节点在不同子树中的最远距离和次远的距离(在递归中进行动态规划就可以),第二次DFS从根向下更新出终于答案.对于每次更新到的节点u,他的最远距离可能是来自u的子树,或者是u的父亲节点的最远

HDU 2196 Computer 树形DP 经典题

给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权,放在数组cost中 令tree(i)表示以节点i为根的子树 对于节点i,离该节点最远的点要不就是在tree(i)中,要不就是在father(i)上面 令: dp[i][1] : 在子树tree(i)中,离i最远的距离 dp[i][2] : 在子树tree(i)中,离i第二远的距离 (递推的时候需要)

HDU 2169 Computer[树形dp]

Computer 时限:1000ms Problem Description A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of s

HDU 2196(树形dp

题目:求出一棵树上的所有点到其他点的最长距离. 思路:取一个根节点进行dfs,先求出每个节点到子节点的最长路和次长路(也就是与最长路不同的最长的路,有可能与最长路长度相等),并记录最长路和次长路通过的相邻节点的标号.然后进行第二次dfs,考虑最长路是通过父节点的情况,如果该节点v在父节点的最长路上,那么需要取次长路,否则就取最长路. 第二次dfs的时候最长路的通过节点还是要更新,因为若某个父节点的最长路是朝祖先走的,那么其子节点的最长路一定朝祖先走,且与v是否在父节点向下的最长路上无关. #in

HDU 2196 Computer 经典树形DP

一开始看错题了,后来发现原来是在一颗带权的树上面求出距离每一个点的最长距离,做两次dfs就好,具体的看注释? #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #incl

hdu 1011(树形dp)

Mark.看着吴神博客写的,还未完全懂. 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string>

HDU 2196Computer(树形DP)

给你一颗边带权值的树,求树上的每一点距离其最远的一个点的距离 比较典型的题了,主要方法是进行两次DFS,第一次DFS求出每一个点距离它的子树的最远距离和次远距离,然后第二次DFS从父节点传过来另一侧的树上的距离它的最远距离进行一次比较便可得出任意点的最远距离了 之所以需要记录最远和次远是为了辨别父节点的最远距离是否是根据自己得来,如果是的话应该选择父节点的次远距离,保证结果的准确性 1 //#pragma comment(linker,"/STACK:102400000,102400000&qu

树形DP [HDU 2196] Computer

Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3526    Accepted Submission(s): 1788 Problem Description A school bought the first computer some time ago(so this computer's id is 1). D

HDU 2196 树状dp 求树中节点之间的最长距离

Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3749    Accepted Submission(s): 1892 Problem Description A school bought the first computer some time ago(so this computer's id is 1). Du

HDU-2196 Computer (树形DP)

最近在看树形DP,这题应该是树形DP的经典题了,写完以后还是有点感觉的.之后看了discuss可以用树分治来做,以后再试一试. 题目大意 找到带权树上离每个点的最远点.︿( ̄︶ ̄)︿ 题解: 对于每一个点的最远点,就是以这个点为根到所有叶子节点的最长距离.但是如果确定根的话,除了根节点外,只能找到每个节点(度数-1)个子树的最大值,剩下一个子树是该节点当前的父亲节点. 所以当前节点的最远点在当前节点子树的所有叶子节点以及父亲节点的最远点上(当父亲节点的最远点不在当前节点的子树上时), 如果父亲节