標籤:
太開心了,終於做出來了。
先卡了半年的題啊~~~~
首先一種簡單的做法,就是找到直徑的兩端,分別dfs一下,求出兩端到每個點分別的距離取最大值就ok。
/********************************************************Problem : 2196 ( Computer ) Judge Status : AcceptedRunId : 15495812 Language : G++ Author : G_lory********************************************************/#include<bits/stdc++.h>using namespace std;const int N = 100005;vector<int> G[N];vector<int> L[N];int dis1[N];int dis2[N];int len;int fa, fb;void dfs(int pre, int v, int d[], int x){ d[v] = x; for (int i = 0; i < G[v].size(); ++i) { int u = G[v][i]; if (u == pre) continue; dfs(v, u, d, x + L[v][i]); } if (x > len) { len = x; fa = v; }}int main(){ std::ios::sync_with_stdio(false); int n; int a, b; while (cin >> n) { for (int i = 0; i <= n; ++i) { G[i].clear(); L[i].clear(); } for (int i = 2; i <= n; ++i) { cin >> a >> b; G[a].push_back(i); G[i].push_back(a); L[a].push_back(b); L[i].push_back(b); } len = -1; dfs(-1, 1, dis1, 0); len = -1; dfs(-1, fa, dis1, 0); len = -1; dfs(-1, fa, dis2, 0); for (int i = 1; i <= n; ++i) { cout << max(dis1[i], dis2[i]) << endl; } } return 0;}
然後是樹形dp的做法。真心不懂不懂不懂啊啊啊啊啊!
翻來覆去的看好多大牛小牛的部落格,最後終於看kuangbin巨巨的代碼明白了。。。心酸。。。看了兩三天。。。
對於每一個點,它的最長距離一定是它的子樹鏈,或者經過它的父節點的路徑。(廢話)
第一遍dfs求得是每一個結點子樹的最長的次長路徑。
第二次dfs是用父節點更新它的每一個子節點。
如果該節點是最長鏈上的,那麼就用次長鏈更新,否則用最長鏈更新。
舉個栗子。
輸入資料:
5
1 1
2 1
3 1
3 1
通過第一遍dfs可以求出
dis[1]=3,sdis[1]=0;
dis[2]=2,sdis[2]=0;
dis[3]=1,sdis[3]=1;
dis[4]=0,sdis[4]=0;
dis[5]=0,sdis[5]=0.
然後第二遍dfs從1開始更新。
2是1的最長子路徑,sdis[1]+d[1][2]>sdis[2],sdis[2]=1;
3是2的最長子路徑,sdis[2]+d[2][3]>dis[3],dis[3]=2,sdis[3]=1; 同時更新3的最長子路徑為位置為2
dis[3]+d[3][4]>dis[4],dis[4]=3
dis[3]+d[3][5]>dis[5],dis[5]=3
寫的囉嗦的,反正就是這麼回事 ^_^
/****************************************************Problem : 2196 ( Computer ) Judge Status : AcceptedRunId : 15496928 Language : G++ Author : G_lory****************************************************/#include <bits/stdc++.h>using namespace std;const int N = 100005;vector<int> G[N];vector<int> L[N];int dis[N];int sdis[N];int id[N];void dfs(int v, int pre){ for (int i = 0; i < G[v].size(); ++i) { int u = G[v][i]; if (u == pre) continue; dfs(u, v); if (dis[v] < dis[u] + L[v][i]) { sdis[v] = dis[v]; dis[v] = dis[u] + L[v][i]; id[v] = u; } else if (sdis[v] < dis[u] + L[v][i]) { sdis[v] = dis[u] + L[v][i]; } }}void dfs1(int v, int pre){ for (unsigned i = 0; i < G[v].size(); ++i) { int u = G[v][i]; if (u == pre) continue; if (u == id[v]) { if (L[v][i] + sdis[v] > dis[u]) { sdis[u] = dis[u]; dis[u] = L[v][i] + sdis[v]; id[u] = v; } else if (L[v][i] + sdis[v] > sdis[u]) { sdis[u] = L[v][i] + sdis[v]; } } else { if (L[v][i] + dis[v] > dis[u]) { sdis[u] = dis[u]; dis[u] = L[v][i] + dis[v]; id[u] = v; } else if (L[v][i] + dis[v] > sdis[u]) { sdis[u] = L[v][i] + dis[v]; } } dfs1(u, v); }}int main(){ std::ios::sync_with_stdio(false); int n; int a, b; while (cin >> n) { memset(dis, 0, sizeof dis); memset(sdis, 0, sizeof sdis); for (int i = 0; i <= n; ++i) { G[i].clear(); L[i].clear(); } for (int i = 2; i <= n; ++i) { cin >> a >> b; G[a].push_back(i); G[i].push_back(a); L[a].push_back(b); L[i].push_back(b); } dfs(1, -1); dfs1(1, -1); for (int i = 1; i <= n; ++i) { cout << dis[i] << endl; } } return 0;}
HDU2196-Computer(樹形dp)