题意:给你一颗树,选择一个三个点构成的集合,使得这三个点不在一条直线上(意思就是 从一个点出发,用一条不回头的线不能将这三个点连起来)问一共有多少个这样的集合
http://acm.hdu.edu.cn/showproblem.php?pid=4705
思路 :先求出一共有多少个集合,就是Cn3 =(n-2)*(n-1)*n/6 ; 然后再求不符合条件的个数
求不符合条件的集合时 比如上图:先以2为中心然后在3中选一个,在4,5,1,6,7,8,9中选一个种类数就是1×7
然后在4中选一个,在5,1,6,7,8,9中选一个种类数是1×6;
依此递归求解;
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
vector<ll> p[100001];
ll size[100001];
ll ans,n;
void dfs(ll u,ll pa){
size[u]=1;
ll len=p[u].size();
for(ll i=0;i<len;i++){
ll v=p[u][i];
if(v==pa)continue;
dfs(v,u);
size[u]+=size[v];
ans+=(size[v]*(n-size[u]));
}
}
int main(){
while(cin>>n){
for(ll i=1;i<=n;i++){
p[i].clear();
}
ll x,y;
for(ll i=0;i<n-1;i++){
cin>>x>>y;
p[x].push_back(y);
p[y].push_back(x);
}
memset(size,0,sizeof(size));
ans=0;
dfs(1,0);
cout<<(n-2)*(n-1)*n/6-ans<<endl;
}
return 0;
}