您的位置:首页 > 其它

Hdu 2196 Computer

2016-07-13 19:27 357 查看
题意:给你一棵树,让你求出每个点离树上最远的距离.

...不会做,想了半天查了题解。

对于每一个点最远距离,要么是往下走,要么是从父节点下来的。

dp[u][0]表示跑儿子路的最大值,dp[u][1]表示跑儿子路的次大值.为什么要记录次大值呢。

dp[u][2]表示往父亲那里跑的最大值.

dp[v][2]照常理来说应该是等于max(dp[u][0],dp[u][2])+w[u][v].但是dp[u][0]有可能是从dp[v][0]那里得到的,如下图那种情况dp[u][0]就是跑向v的那里.这种情况下就要用max(dp[u][1],dp[u][2])+w[u][v];

#include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#include <set>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;
#define X first
#define Y second
#define mp(a,b) make_pair(a,b)
#define pb push_back
#define sd(x) scanf("%d",&(x))
#define Pi acos(-1.0)
#define sf(x) scanf("%lf",&(x))
#define ss(x) scanf("%s",(x))
#define maxn 10005
const int inf=0x3f3f3f3f;
const ll mod=1000000007;
struct node
{
int v,w,next;
}E[maxn];
int top;
int head[maxn];
void add(int u,int v,int w)
{
E[top].v=v;
E[top].w=w;
E[top].next=head[u];
head[u]=top++;
}
int dp[maxn][3];
void dfs(int u)
{
int mm=0,sm=0,v,pa;
for(int i=head[u];i!=-1;i=E[i].next)
{
v=E[i].v;
dfs(v);
pa=dp[v][0]+E[i].w;
if(pa>=mm)
{
sm=mm;
mm=pa;
}
else if(pa>=sm)
sm=pa;
}
dp[u][0]=mm;
dp[u][1]=sm;
}
void dfs2(int u)
{
int v;
for(int i=head[u];i!=-1;i=E[i].next)
{
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()
{
#ifdef local
freopen("in","r",stdin);
//freopen("out","w",stdout);
int _time=clock();
#endif
int n;
while(cin>>n){
top=0;
memset(head,-1,sizeof head);
for(int v=2;v<=n;v++)
{
int u,w;
scanf("%d%d",&u,&w);
add(u,v,w);
}
dfs(1);
dp[1][2]=0;
dfs2(1);
for(int i=1;i<=n;i++)
{
printf("%d\n",max(dp[i][0],dp[i][2]));
}
}
#ifdef local
printf("time: %d\n",int(clock()-_time));
#endif
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: