D:
It is difficult to find the number of non-overlapping paths in a tree. It is much easier to reverse the process. c (n, 2) * c (n, 2) minus illegal
For each subtree, it can be divided into two types: intersection within the subtree and extension of external points to the inside of the subtree. Just cut them out.
[Cpp]
# Include <cstdio>
# Include <vector>
# Include <iostream>
Using namespace std;
Int a [80001];
Vector <int> edge [80001];
Long ans;
Int n;
Void dfs (int u, int f)
{
A [u] = 1;
Long in = 0;
For (int I = 0; I <edge [u]. size (); I ++)
{
Int v = edge [u] [I];
If (v = f) continue;
Dfs (v, u );
In + = (long) a [u] * a [v];
A [u] + = a [v];
}
Ans-= in * (in + 2 * (long) a [u] * (n-a [u]);
}
Int main ()
{
Int a, B, I;
Cin> n;
For (I = 1; I <n; I ++)
{
Cin> a> B;
Edge [a]. push_back (B );
Edge [B]. push_back ();
}
Ans = (long) n * (n-1)/2;
Ans * = ans;
Dfs (1, 0 );
Cout <ans <endl;
Return 0;
}
# Include <cstdio>
# Include <vector>
# Include <iostream>
Using namespace std;
Int a [80001];
Vector <int> edge [80001];
Long ans;
Int n;
Void dfs (int u, int f)
{
A [u] = 1;
Long in = 0;
For (int I = 0; I <edge [u]. size (); I ++)
{
Int v = edge [u] [I];
If (v = f) continue;
Dfs (v, u );
In + = (long) a [u] * a [v];
A [u] + = a [v];
}
Ans-= in * (in + 2 * (long) a [u] * (n-a [u]);
}
Int main ()
{
Int a, B, I;
Cin> n;
For (I = 1; I <n; I ++)
{
Cin> a> B;
Edge [a]. push_back (B );
Edge [B]. push_back ();
}
Ans = (long) n * (n-1)/2;
Ans * = ans;
Dfs (1, 0 );
Cout <ans <endl;
Return 0;
}