标签:
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;
}标签:
原文地址:http://blog.csdn.net/qzh_1430586275/article/details/51894665