动态规划
线性DP
背包DP
0-1背包
完全背包
多重背包
二进制优化
单调队列优化
混合背包
区间DP
树形DP
例题2:HDU 2196 Computer
题意描述:
给出一棵 n n n 个结点的无根树,求出每个结点所能到达的最远点的距离。
分析
代码
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int maxn = 1e4+5;
struct Edge {
int v, w;
Edge(){}
Edge(int v,int w):v(v),w(w){}
};
int n;
vector<Edge> G[maxn];
int dp[maxn][3], id[maxn];
void dfs(int u, int fa) { // 正向最大 and 正向次大
for(auto ed : G[u]) {
int v = ed.v;
int w = ed.w;
if(v == fa) continue;
dfs(v, u);
// 回溯
int t = dp[v][0] + w;
if(t > dp[u][0]) {
dp[u][1] = dp[u][0];
dp[u][0] = t;
id[u] = v;
}
else if(t > dp[u][1]) dp[u][1] = t;
}
/*for(auto ed:G[u]) {
int v = ed.v;
int w = ed.w;
if(v == fa) continue;
dfs(v, u);
if(dp[u][0] < dp[v][0] + w) {
dp[u][0] = dp[v][0] + w;
id[u] = v;
}
}
for(auto ed:G[u]) {
int v = ed.v;
int w = ed.w;
if(v == fa || id[u] == v) continue;
dp[u][1] = max(dp[u][1], dp[v][0] + w);
}*/
}
void dfss(int u, int fa) { // 反向最大
for(auto ed : G[u]) {
int v = ed.v;
int w = ed.w;
if(v == fa) continue;
if(v == id[u]) dp[v][2] = max(dp[u][1], dp[u][2]) + w;
else dp[v][2] = max(dp[u][0], dp[u][2]) + w;
dfss(v, u);
}
}
void add(int u, int v, int w){
G[u].push_back(Edge(v, w));
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
while(cin >> n) {
mem(dp, 0); mem(id, 0);
for(int i=1;i<=n;i++) G[i].clear();
for(int i=2;i<=n;i++) {
int u, w; cin >> u >> w;
add(i, u, w);
add(u, i, w);
}
dfs(1, 0);
dfss(1, 0);
for(int i=1;i<=n;i++) {
cout << max(dp[i][0], dp[i][2]) << "\n";
}
}
return 0;
}