题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4705
题目大意:
给出一颗树,然后找出在这个树上,不能一线画出的3个点,{A,B,C},问一共有多少个这样的点?
思路:
用树形DP(由叶到根的方式)找出所有能够一线连的点的数量,记为aline,再用总数量也就是C(n,3)减去aline,即可得出不能一线连的3个点的数量。
#pragma comment ( linker,"/STACK:102400000,102400000")
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
#define N 100010
typedef long long LL;
LL n;
int head[N],tot;
vector<int> g[N];
int dp[N];
LL aline;
void dfs(int u,int pre)
{
dp[u]=0;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==pre)
continue;
dfs(v,u);
aline+=dp[u]*dp[v];//记录一线连总个数
dp[u]+=dp[v];
}
dp[u]++;
aline+=(n-dp[u])*(dp[u]-1);
//printf("u = %d aline = %d\n",u,aline);
}
int main()
{
int i,j,u,v;
while(scanf("%lld",&n)!=EOF)
{
aline=0;
for(i=0;i<=n;i++)
g[i].clear();
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,-1);
LL all=(n*(n-1)*(n-2))/6;
all-=aline;
printf("%lld\n",all);
}
return 0;
}