hdu 2196 Computer
题 意:给你一颗树,让你求树上任意顶点到其他节点的最大距离。
数据范围:
1<=N<=1e4
输入样例:
5
1 1
2 1
3 1
1 1
输出样例:
3
2
3
4
4
思 路:感谢大佬的图
收获:对树形dp有了更加深刻的认识把
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e4+4;
int dp[maxn][4];
//dp[i][0]表示节点i到所有子节点的最大距离
//dp[i][1]表示节点i到
struct edge{
int to,value;
};
bool vis[maxn];
vector<edge> vec[maxn];
int n;
int dfs(int u){ //这个是常规操作
vis[u] = true;
dp[u][0] = 0;
for(int i=0;i<vec[u].size();i++){
int v = vec[u][i].to;
int w = vec[u][i].value;
if(vis[v])continue;
dp[u][0] = max(dp[u][0],dfs(v)+w);
}
return dp[u][0];
}
void init(){
for(int i=1;i<maxn;i++)vec[i].clear();
memset(dp,0,sizeof(dp));
memset(vis,false,sizeof(vis));
}
void dfs1(int u){
vis[u] = true;
int max1=0,v1=0,max2,v2;
for(int i=0;i<vec[u].size();i++){
int v = vec[u][i].to;
int w = vec[u][i].value;
if(vis[v]) continue;
int tmp = dp[v][0] + w;
if(tmp > max1){
max2 = max1;v2 = v1;
max1 = tmp;v1 = v;
}else if(tmp == max1 || tmp > max2){
v2 = v;max2 = tmp;
}
}
if(u!=1){
int tmp = dp[u][1];
if(tmp > max1){
max2 = max1;v2 = v1;
max1 = tmp; v1 = -1;
}else if(tmp == max1 || tmp > max2){
max2 = tmp; v2 = -1;
}
}
for(int i=0;i<vec[u].size();i++){
int v = vec[u][i].to;
int w = vec[u][i].value;
if(vis[v]) continue;
if(v == v1){
dp[v][1] = max2 + w;
}else{
dp[v][1] = max1 + w;
}
dfs1(v);
}
}
int main(){
while(~scanf("%d",&n)){
init();
for(int i=2;i<=n;i++){
int v,val;
scanf("%d %d",&v,&val);
edge e;
e.to = v;
e.value = val;
vec[i].push_back(e);
e.to = i;
vec[v].push_back(e);
}
dfs(1);
memset(vis,false,sizeof(vis));
dfs1(1);
for(int i=1;i<=n;i++){
printf("%d%c",max(dp[i][0],dp[i][1]),'\n');
}
}
return 0;
}
/*
5
1 1
2 1
3 2
1 1
*/