一棵带边权的树,对每个节点,求离这个节点最远的节点到它的距离...
两边dps,第一遍记录一下每个节点的子树当中最深和次深的深度和该深度来源节点。第二遍从父节点取出一个最长的并且不通过当前节点的最长的深度去更新当前节点的最深次深这两个值和其来源节点,然后该节点记录的最大深度就是这个节点的答案了。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <memory.h> #include <vector> using namespace std; typedef long long ll; const int maxn=12000; struct edge { int v,w; edge(){} edge(int x,int y) { v=x; w=y; } }; vector<edge> g[maxn]; int n,m; int x,y; int way[maxn][3]; int tg[maxn][3]; int ans[maxn]; void dfs(int u,int fa) { way[u][0]=way[u][1]=0; tg[u][0]=tg[u][1]=u; for (int j=0; j<g[u].size(); j++) { int v=g[u][j].v; if (v==fa) continue; dfs(v,u); if (way[v][0]+g[u][j].w>way[u][0]) { way[u][1]=way[u][0]; tg[u][1]=tg[u][0]; way[u][0]=way[v][0]+g[u][j].w; tg[u][0]=v; } else if (way[v][0]+g[u][j].w>way[u][1]) { way[u][1]=way[v][0]+g[u][j].w; tg[u][1]=v; } } } void dfs2(int u,int fa,int wei) { int tmp; if (tg[fa][0]!=u) tmp=way[fa][0]; else tmp=way[fa][1]; int id; if (tmp+wei>way[u][0]) { way[u][1]=way[u][0]; tg[u][1]=tg[u][0]; way[u][0]=tmp+wei; tg[u][0]=fa; } else if (tmp+wei>way[u][1]) { way[u][1]=tmp+wei; tg[u][1]=fa; } ans[u]=way[u][0]; for (int j=0; j<g[u].size(); j++) { int v=g[u][j].v; if (v==fa) continue; dfs2(v,u,g[u][j].w); } } int main() { // freopen("in.txt","r",stdin); memset(ans,0,sizeof ans); memset(tg,0,sizeof tg); memset(way,0,sizeof way); scanf("%d",&n); for (int i=2; i<=n; i++) { scanf("%d%d",&x,&y); g[i].push_back(edge(x,y)); g[x].push_back(edge(i,y)); } dfs(1,0); dfs2(1,0,0); for (int i=1; i<=n; i++) printf("%d\n",ans[i]); return 0; }