思路:枚举能是A,B,C在一条简单路径上的中点。 计算多少个几何能满足。在用总数减去
#pragma comment(linker, "/STACK:16777216") #include<map> #include<set> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define Maxn 200010 #define Maxm 300010 #define LL __int64 #define Abs(x) ((x)>0?(x):(-x)) #define lson(x) (x<<1) #define rson(x) (x<<1|1) #define inf 0x7fffffff #define Mod 1000000007 using namespace std; LL num[Maxn]; LL snum[Maxn],vi[Maxn]; vector<LL> son[Maxn]; vector<int> head[Maxn]; void dfs(int u) { int i,v,sz; vi[u]=1; snum[u]=1; sz=head[u].size(); for(i=0;i<sz;i++){ v=head[u][i]; if(vi[v]) continue; dfs(v); snum[u]+=snum[v]; son[u].push_back(snum[v]); } } void predfs(int u,LL sum) { int i,v,sz; vi[u]=1; if(sum) son[u].push_back(sum); sz=head[u].size(); for(i=0;i<sz;i++){ v=head[u][i]; if(vi[v]) continue; predfs(v,sum+snum[u]-snum[v]); } } int main() { int i,j,u,v; LL n; while(scanf("%I64d",&n)!=EOF) { memset(snum,0,sizeof(snum)); memset(vi,0,sizeof(vi)); memset(num,0,sizeof(num)); for(i=0;i<=n;i++){ son[i].clear(); head[i].clear(); } for(i=1;i<n;i++){ scanf("%d%d",&u,&v); head[u].push_back(v); head[v].push_back(u); } dfs(1); memset(vi,0,sizeof(vi)); predfs(1,0); LL ans=n*(n-1)*(n-2)/6; //cout<<ans<<endl; LL sz; LL sum=0; for(i=1;i<=n;i++){ sz=son[i].size(); sum=0; for(j=0;j<sz;j++) sum+=son[i][j]; for(j=0;j<sz-1;j++) ans-=(son[i][j]*(sum-=son[i][j])); } printf("%I64d ",ans); } return 0; }