1、题意:http://www.lydsy.com/JudgeOnline/problem.php?id=3522
2、分析:这道题有两种情况,第一个是三个点在同一个链上,这显然不可能了,因为树上的路径是唯一的,第二个情况是三个点距离某个中心的距离相等
那么我们只需枚举中间点,然后在不同子树中dfs一下即可求出答案
#include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define M 10010 #define LL long long inline int read(){ char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while('0' <= ch && ch <= '9'){ x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } struct Edge{ int u, v, next; } G[M]; int head[M], tot; int q[M], fa[M]; int tmp[M / 2], g[M / 2], f[M / 2]; inline void add(int u, int v){ G[++ tot] = (Edge){u, v, head[u]}; head[u] = tot; } inline void dfs(int x, int fa, int deep){ tmp[deep] ++; for(int i = head[x]; i != -1; i = G[i].next) if(G[i].v != fa){ dfs(G[i].v, x, deep + 1); } } int main(){ int n = read(); memset(head, -1, sizeof(head)); for(int i = 1; i < n; i ++){ int u = read(), v = read(); add(u, v); add(v, u); } LL ans = 0; for(int i = 1; i <= n; i ++){ memset(f, 0, sizeof(f)); memset(g, 0, sizeof(g)); for(int j = head[i]; j != -1; j = G[j].next){ memset(tmp, 0, sizeof(tmp)); dfs(G[j].v, i, 1); for(int k = 1; k <= n; k ++){ ans += (LL)(g[k] * tmp[k]); g[k] += f[k] * tmp[k]; f[k] += tmp[k]; } } } printf("%lld\n", ans); return 0; }