N vertices and n-1-1 edges are given. For each vertex, each path passes through, and the degree of prosperity is + 1.
The meaning is that this path uses two edges connected to this vertex and can be combined in any way. Therefore, you need to find out how many cases the edges connected to each vertex can be extended.
Build from the first vertex, there is a sum [I] subnode for the I node, so DP [I] = sum [I] * (n-1-sum [I]), plus the product of the number of nodes in the N subtree of the node/2.
# Include <iostream> # include <cstdio> # include <cmath> # include <queue> # include <cstring> # include <cstdlib> # include <vector> # include <iomanip> # include <algorithm> using namespace STD; const int maxn = 22000; struct edge {int V; int next;} edge [maxn <1]; int next [maxn]; int sum [maxn]; int ans, n, num; void addedge (int u, int v) {edge [num]. next = next [u]; next [u] = num; edge [num ++]. V = V;} void DFS (INT father, int U, int N) {int v, M, temp; For (INT I = next [u]; I! =-1; I = edge [I]. next) {v = edge [I]. v; If (V = Father) {continue;} DFS (u, v, n); sum [u] + = sum [v];} M = sum [u] * (N-1-sum [u]); // cout <father <"" <u <"" <m <"" <sum [u] <Endl; // cout <"___________" <Endl; temp = 0; For (INT I = next [u]; I! =-1; I = edge [I]. next) {v = edge [I]. v; If (V = Father) {continue;} temp + = sum [v] * (sum [u]-sum [v]);} m + = temp/2; // cout <father <"" <u <"<m <" "<sum [u] <Endl; ans = max (ANS, m); sum [u] ++;} int main () {int t; int K = 1; int p, q; scanf ("% d", & T ); while (t --) {scanf ("% d", & N); num = 0; memset (sum, 0, sizeof (SUM); memset (next,-1, sizeof (next); For (INT I = 0; I <n-1; I ++) {scanf ("% d", & P, & Q ); addedge (p, q); addedge (Q, P) ;}ans = 0; DFS (0, 1, n); printf ("case # % d: % d \ n ", k ++, ANS);} return 0 ;}