输出一棵树上,每个点到最远点的距离
思路:先搜两遍找出树的直径,然后在从这两点出发,每个点距离这两点中距离大的就是最远点距离
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int N = 50005;
int n, m;
struct Edge {
int v, w;
Edge() {}
Edge(int v, int w) {
this->v = v;
this->w = w;
}
} edge[N * 2];
int head[N], nxt[N * 2], en;
void addedge(int u, int v, int w) {
edge[en] = Edge(v, w);
nxt[en] = head[u];
head[u] = en++;
}
typedef long long ll;
ll d[N];
queue<int> Q;
int get(int s) {
Q.push(s);
memset(d, -1, sizeof(d));
d[s] = 0;
int ans = s;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
if (d[u] > d[ans]) ans = u;
for (int i = head[u]; i + 1; i = nxt[i]) {
int v = edge[i].v;
int w = edge[i].w;
if (d[v] != -1) continue;
d[v] = d[u] + w;
Q.push(v);
}
}
return ans;
}
ll dp[N];
void gao(int s) {
Q.push(s);
memset(d, -1, sizeof(d));
d[s] = 0;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
dp[u] = max(dp[u], d[u]);
for (int i = head[u]; i + 1; i = nxt[i]) {
int v = edge[i].v;
int w = edge[i].w;
if (d[v] != -1) continue;
d[v] = d[u] + w;
Q.push(v);
}
}
}
inline void scanf_(int &num)//无负数
{
char in;
while((in=getchar()) > '9' || in<'0') ;
num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
num*=10,num+=in-'0';
}
int main() {
while (~scanf("%d", &n)) {
en = 0;
memset(head, -1, sizeof(head));
int x, y, z;
for (int i = 2; i <= n; i++) {
scanf_(y); scanf_(z);
addedge(i, y, z);
addedge(y, i, z);
}
int s = get(1);
int e = get(s);
memset(dp, 0, sizeof(dp));
gao(s);
gao(e);
for (int i = 1; i <= n; i++) printf("%I64d\n", dp[i]);
}
return 0;
}