氪金带东
实验室里原先有一台电脑(编号为1),最近氪金带师咕咕东又为实验室购置了N-1台电脑,编号为2到N。每台电脑都用网线连接到一台先前安装的电脑上。但是咕咕东担心网速太慢,他希望知道第i台电脑到其他电脑的最大网线长度,但是可怜的咕咕东在不久前刚刚遭受了宇宙射线的降智打击,请你帮帮他。
提示: 样例输入对应这个图,从这个图中你可以看出,距离1号电脑最远的电脑是4号电脑,他们之间的距离是3。 4号电脑与5号电脑都是距离2号电脑最远的点,故其答案是2。5号电脑距离3号电脑最远,故对于3号电脑来说它的答案是3。同样的我们可以计算出4号电脑和5号电脑的答案是4.
Input
输入文件包含多组测试数据。对于每组测试数据,第一行一个整数N (N<=10000),接下来有N-1行,每一行两个数,对于第i行的两个数,它们表示与i号电脑连接的电脑编号以及它们之间网线的长度。网线的总长度不会超过10^9,每个数之间用一个空格隔开。
Output
对于每组测试数据输出N行,第i行表示i号电脑的答案 (1<=i<=N).
Smple Input
5
1 1
2 1
3 1
1 1
Sample Output
3
2
3
4
4
我的思路:
这道题是要求树的任意一个节点到树内其他点的最远距离。可以利用求树的直径的方法(在树中任意选择一个点,找到一个距离当前的点最远的点v0,在找到一个距离v0最远的点v1,v0-v1即是树的直径),找到v0,v1,然后分别计算v0,v1到所求点的距离,选择最大的距离,就是要得到的答案。
我的总结:
要尽量降低算法的复杂度,不然TLE就很尴尬了。。。
我的代码:
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct edg
{
long long dot,weight;
};
vector <edg> tree[10001];
long long n,a,b,v1,v2,vis[10001],maxn,node,ans[10001];
void init(){for(long long i=1;i<=n;i++) vis[i]=1;maxn=0;}
void dfs(long long x,long long length)
{
vis[x]=0;
if(length>maxn) maxn=length,node=x;
for(long long i=0;i<tree[x].size();i++)
{
if(vis[tree[x][i].dot])
{
dfs(tree[x][i].dot,length+tree[x][i].weight);
}
}
}
void dfs1(long long x,long long length)
{
vis[x]=0;
if(length>maxn) maxn=length,node=x;
for(long long i=0;i<tree[x].size();i++)
{
if(vis[tree[x][i].dot])
{
ans[tree[x][i].dot]=length+tree[x][i].weight;
dfs1(tree[x][i].dot,length+tree[x][i].weight);
}
}
}
void dfs2(long long x,long long length)
{
vis[x]=0;
if(length>maxn) maxn=length,node=x;
for(long long i=0;i<tree[x].size();i++)
{
if(vis[tree[x][i].dot])
{
ans[tree[x][i].dot]=ans[tree[x][i].dot]<(length+tree[x][i].weight)?(length+tree[x][i].weight):ans[tree[x][i].dot];
dfs2(tree[x][i].dot,length+tree[x][i].weight);
}
}
}
int main()
{
while(scanf("%lld",&n)!=EOF)
{
if(n==1) {
printf("0\n");continue;}
for(long long i=2;i<n+1;i++)
{
scanf("%lld%lld",&a,&b);
tree[i].push_back({a,b});
tree[a].push_back({i,b});
}
init();
dfs(1,0);
v1=node;
init();
ans[v1]=0;
dfs1(v1,0);
v2=node;
init();
dfs2(v2,0);
for(long long i=1;i<=n;i++)
{
printf("%lld\n",ans[i]);
}
for(int i=1;i<=n;i++) tree[i].clear();
}
return 0;
}