题意: 给你n太台电脑 及 相邻之间的 距离 让你求出 每台电脑的离它最远的电脑的离;
思路:树形dp,题意给出一棵树,求离每个节点最远的点的距离, 两种情况1,以该节点s作为根节点的子树中的离该节点最长距离x。2,其父树中离该节点的最长距离y。答案就是max(x, y);
需要注意的是:父树中的最长距离有可能经过s点, 这时候就要选父树中次长的路径(求第一种时顺便求出)
ps:建图时是双向边 不明白在纸上画图走一遍样例
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#define N 10005<<1
#define INF 10000000
#define LL long long
#define eps 10E-9
#define mem(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define w(a) while(a)
#define s(a) scanf("%d",&a)
#define ss(a,b) scanf("%d%d",&a,&b)
#define sss(a,b,c) scanf("%d%d%d",&a,&b,&c)
using namespace std;
int dp[N][3];//设dp[i][1]、dp[i][0]第i节点的子树方向最长距离、次长距离 ,设dp[i][2]为第i节点的父树方向最长距离
int fnext[N];//与第i条边同起点的下条边的位置
int head[N];//以i为起点的第一条边的位置
int edge[N];//第i条边的终点
int cost[N];//第i条边的长度
int vis[N];//优化 用不用都行
void add(int i, int a, int b, int c){
edge[i] = b;
fnext[i] = head[a];
head[a] = i;
cost[i] = c;
}
void tree_dp1(int a, int b){
for(int i=head[a]; i!=-1; i=fnext[i]){
int k = edge[i];
if( k!= b){
tree_dp1(k, a);
if(dp[a][0] < cost[i] + dp[k][0]){
dp[a][1] = dp[a][0];
dp[a][0] = cost[i] + dp[k][0];
}
else if(dp[a][1] < cost[i] + dp[k][0]) dp[a][1] = cost[i] + dp[k][0];
}
}
}
void tree_dp2(int a, int b){
int len = 0;
for(int i=head[a]; i!=-1; i=fnext[i]){
if(edge[i] == b){
len = cost[i]; break;
}
}
if(b != -1 && !vis[a]){
dp[a][2] = dp[b][2];
if(dp[a][0] + len == dp[b][0] && dp[b][1] > dp[a][2]) dp[a][2] = dp[b][1];
if(dp[a][0] + len != dp[b][0] && dp[b][0] > dp[a][2]) dp[a][2] = dp[b][0];
dp[a][2] += len ;
vis[a] = 1;
}
for(int i=head[a]; i!=-1; i=fnext[i]){
if(edge[i] !=b ) tree_dp2(edge[i], a);
}
}
int main(){
int n, j, i, a, b;
w(~s(n)){
mem(vis);
mem(dp);
mem1(fnext);
mem1(head);
for(i=2, j=1; i<=n; i++){
ss(a, b);
add(j++, i, a, b);
add(j++, a, i, b);
}
tree_dp1(1, -1);//求子树最长距离
tree_dp2(1, -1);//求父树最长距离
for(int i=1; i<=n; i++) printf("%d\n",max(dp[i][0],dp[i][2]));
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。