During the competition, due to the incomplete Consideration of the previous algorithm, the competition was completed quickly, but after a long time of tangle, as I wrote in the original method, I had to open multiple arrays for various judgments, although it is still A, it must be easy to write.
Question:
Each edge has the right value for a tree. Now, we need to remove one edge and the remaining two trees have the least weight for the longer longest path to multiply the edge, output the number of the edge. If there are multiple solutions, the smaller one will be output.
Solution:
I will not talk about code and methods. After the game, I learned a new method, which is actually very simple, but I have never written it like this.
First, find the longest path. If the removed edge is not the longest path, the result is that the edge weight is multiplied by the longest path.
If the removed edge is on the longest path, the two-way dfs is performed on the longest path, and the longest path in the subtree below a node is obtained each time.
Add the code.
/*************************************** * ******* Author: jayYeCreated Time: 2013-8-15 18: 07: 13 File Name: zzz. cpp *************************************** * ********/# pragma comment (linker, "/STACK: Running bytes, 00000000") # include <stdio. h> # include <string. h ># include <algorithm> using namespace std; const int maxn = 100000; struct EDGE {int to, next, val, id;} edge [maxn * 2 + 10]; int head [maxn + 10], E, dp [maxn + 1 0] [4], p [maxn + 10], dep [maxn + 10], ee [maxn + 10]; bool vis [maxn + 10]; void init (int n) {for (int I = 1; I <= n; I ++) head [I] =-1; E = 0 ;} void newedge (int u, int to, int val, int id) {edge [E]. to = to; edge [E]. val = val; edge [E]. id = id; edge [E]. next = head [u]; head [u] = E ++;} // find the depth of each node, the biggest depth must be the void finddep (int u, int pre) {dep [u] = dep [pre] + 1; p [u] = pre; for (int I = head [u]; I! =-1; I = edge [I]. next) {int to = edge [I]. to; if (to = pre) continue; finddep (to, u) ;}} int max (int a, int B) {return a> B? A: B;} // dp [u] [0] indicates the longest path from the node to the subtree. dp [u] [1] indicates the second long path, dp [u] [2] indicates the longest void cal (int u, int pre) in the tree of this node) {dp [u] [0] = dp [u] [1] = dp [u] [2] = 0; for (int I = head [u]; I! =-1; I = edge [I]. next) {int to = edge [I]. to; if (to = pre) continue; cal (to, u); int now = dp [to] [0] + 1; if (now> = dp [u] [0]) {dp [u] [1] = dp [u] [0]; dp [u] [0] = now;} else if (now> dp [u] [1]) dp [u] [1] = now; dp [u] [2] = max (dp [u] [2], dp [to] [2]);} dp [u] [2] = max (dp [u] [2], dp [u] [1] + dp [u] [0]); // printf ("% d \ n", u, dp [u] [2]);} int mxlen; // The longest void dfs (int u, int pre) {for (int I = head [u]; I! =-1; I = edge [I]. next) {int to = edge [I]. to; int val = edge [I]. val; int id = edge [I]. id; if (to = pre) continue; dfs (to, u); if (vis [u] & vis [to]) // edge on the longest path ee [id] = max (ee [id], val * dp [to] [2]); else ee [id] = val * mxlen; // edge is not on the longest path} int main () {int n, I, j, u, to, val; int t, cas = 1; scanf ("% d ", & t); while (t --) {scanf ("% d", & n); init (n); for (I = 1; I <= n-1; I ++) {scanf ("% d", & u, & to, & val); n Ewedge (u, to, val, I); newedge (to, u, val, I);} dep [0] =-1; finddep (1, 0 ); u = 1; for (I = 1; I <= n; I ++) if (dep [I]> dep [u]) u = I; finddep (u, 0); to = 1; for (I = 1; I <= n; I ++) if (dep [I]> dep [to]) to = I; // u, to is the two ends of the longest path for (I = 1; I <= n; I ++) vis [I] = 0; int cur =; while (cur! = 0) {vis [cur] = 1; cur = p [cur];} mxlen = dep [to]; for (I = 1; I <= n-1; I ++) ee [I] = 0; // both directions are dfs once cal (u,-1); dfs (u,-1); cal (, -1); dfs (to,-1); int ans = 1; for (I = 1; I <= n-1; I ++) if (ee [I] <ee [ans]) ans = I; printf ("Case # % d: % d \ n", cas ++, ans );} return 0 ;}