Tangled issues. After two days, I still read the code of Daniel. Thank you for your summary.
The train of thought is to use DFS twice. Premise: when building a tree, you can build it from the undirected edge. The first DFS is to find the longest path and the second long path from the root node to other nodes (the second long path is not the sub path of the longest path, that is, it is not on the same path .)
How does one obtain the longest path from one node to another? 1. The longest path may be obtained from this node. 2. select another path from the parent node of the node.
In this case, the longest Path obtained by the first DFS is the required result. In Case 2: The next long path obtained from the first DFS is the result.
In addition, because it is a undirected Edge building, the first DFS from bottom to top search, the second DFS from top to bottom search.
Implementation: Define DP [I] to indicate the longest path from I to other nodes. F [I] indicates the longest path from node I to its child node. L [I] indicates the second long path from node I to its child node. Dir [I] indicates the direction of the longest path, to prevent the longest path from repeating with the second long path.
Core code:
void dfs_0(int r) {
if(f[r]) return ;
int len = g[r].size();
if(len == 0) return ;
int i, max = -1, flag = -1, flag1 = -1, c;
for(i = 0; i < len; i++) {
c = g[r][i].c;
dfs_0(c);
if(f[c] + g[r][i].val > max) {
max = f[c] + g[r][i].val;
flag = i;
}
}
f[r] = max;
dir[r] = flag;
max = -1;
for(i = 0; i < len; i++) {
c = g[r][i].c;
if(f[c] + g[r][i].val > max && i != flag) {
max = f[c] + g[r][i].val;
flag1 = i;
}
}
if(flag1 != -1) l[r] = max;
}
void dfs_1(int r) {
int i, len, c;
len = g[r].size();
for(i = 0; i < len; i++) {
c = g[r][i].c;
if(i == dir[r])
dp[c] = max(dp[r], l[r]) + g[r][i].val;
else
dp[c] = max(dp[r], f[r]) + g[r][i].val;
dfs_1(c);
}
}
PS: because the entire tree may have only one edge, the maximum values of F [I] and DP [I] are obtained when the result is output.