dp1[u]:距离u节点的最远子结点的距离,dp2[u]:距离u节点的次远的子结点的距离,up[u]:u节点上方节点的最远距离。
1 void dfs1(int u ,int pre) { 2 for (int i = head[u]; ~i; i = edge[i].next) { 3 int v = edge[i].to, w = edge[i].w; 4 if (v == pre) continue; 5 dfs1(v, u); 6 if (dp1[v] + w > dp1[u]) { 7 dp2[u] = dp1[u]; 8 dp1[u] = dp1[v] + w; 9 son2[u] = son1[u]; 10 son1[u] = v; 11 } else if (dp1[v] + w > dp2[u]) { 12 dp2[u] = dp1[v] + w; 13 son2[u] = v; 14 } 15 } 16 } 17 18 void dfs2(int u,int pre) { 19 for (int i = head[u]; ~i; i = edge[i].next) { 20 int v = edge[i].to, w = edge[i].w; 21 if (v == pre) continue; 22 if (son1[u] != v) { 23 up[v] = max(dp1[u], up[u]) + w; 24 } else { 25 up[v] = max(dp2[u], up[u]) + w; 26 } 27 dfs2(v,u); 28 } 29 }
求树的所有重心:
1 vector<int> ans; 2 int siz[maxn]; 3 4 void dfs(int u, int pre) { 5 siz[u] = 1; 6 bool ok = true; 7 for (register int i = head[u]; ~i; i = edge[i].next) { 8 int v = edge[i].to; 9 if (v == pre) continue; 10 dfs(v, u); 11 siz[u] += siz[v]; 12 if (siz[v] > n/2) ok = false; 13 } 14 if (n-siz[u] > n/2) ok = false; 15 if (ok) { 16 ans.push_back(u); 17 } 18 }