5 1 1 2 1 3 1 1 1
3 2 3 4 4
题意:给定一颗树,求距离每个点的的最远的距离。
解题思路:最远距离来自两部分,一部分是由子节点而来,还有一部分是从父节点而来,两次dfs,一次求出从子节点而来的最大值,次大值,第二次求从父节点而来的,
以前cf一题思路一模一样,研究了好久没看懂,今天终于看懂了。
代码:
/* ***********************************************
Author :xianxingwuguan
Created Time :2014-2-3 18:13:04
File Name :1.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=20020;
int dp[maxn][3],head[maxn],tol;
struct node {
int next,to,val;
}edge[3*maxn];
void add(int u,int v,int w){
edge[tol].next=head[u];
edge[tol].to=v;
edge[tol].val=w;
head[u]=tol++;
}
void dfs1(int u,int fa){
int b1=0,b2=0;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa)continue;
dfs1(v,u);
int ret=dp[v][0]+edge[i].val;
if(ret>=b1){
b2=b1;
b1=ret;
}
else if(ret>=b2)
b2=ret;
}
dp[u][0]=b1;
dp[u][1]=b2;
}
void dfs2(int u,int fa){
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v==fa)continue;
dp[v][2]=max(dp[u][2],dp[v][0]+edge[i].val==dp[u][0]?dp[u][1]:dp[u][0])+edge[i].val;
dfs2(v,u);
}
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int i,j,k,m,n;
while(~scanf("%d",&n)){
memset(head,-1,sizeof(head));tol=0;
memset(dp,0,sizeof(dp));
for(i=2;i<=n;i++){
scanf("%d%d",&j,&k);
add(i,j,k);
add(j,i,k);
}
dfs1(1,-1);
dfs2(1,-1);
for(i=1;i<=n;i++)
printf("%d\n",max(dp[i][0],dp[i][2]));
}
return 0;
}
原文:http://blog.csdn.net/xianxingwuguan1/article/details/18910681