hdu4705Y
这题可以算树形DP吧 树上的递推
对于树上的某个节点 反着算比较好做 就是算有多少有simple路径的
固定某个节点u 另两个节点 有两种取法
1.从不同子树里各选一个
2.从所有子树里选一个 再从以u为跟的子树 外面选一个
求总和
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #pragma comment(linker, "/STACK:16777216") 2 #include <iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<stdlib.h> 7 using namespace std; 8 #define N 100010 9 #define LL __int64 10 struct node 11 { 12 int u,v,next; 13 }ed[N<<1]; 14 int head[N],t; 15 LL sum[N],ans,n; 16 void init() 17 { 18 t = 0; 19 memset(head,-1,sizeof(head)); 20 } 21 void add(int u,int v) 22 { 23 ed[t].u = u; 24 ed[t].v = v; 25 ed[t].next = head[u]; 26 head[u] = t++; 27 } 28 LL dfs(int pre,int u) 29 { 30 int i; 31 LL s=0,ss; 32 sum[u] = 1; 33 for(i = head[u]; i!=-1 ; i = ed[i].next) 34 { 35 int v = ed[i].v; 36 if(v==pre) continue; 37 ss = dfs(u,v); 38 ans+=s*ss; 39 s+=ss; 40 sum[u]+=ss; 41 } 42 ans+=s*(n-sum[u]); 43 return sum[u]; 44 } 45 int main() 46 { 47 int i,u,v; 48 while(scanf("%I64d",&n)!=EOF) 49 { 50 init();ans=0; 51 memset(sum,0,sizeof(sum)); 52 for(i = 1 ; i < n ; i++) 53 { 54 scanf("%d%d",&u,&v); 55 add(u,v); 56 add(v,u); 57 } 58 dfs(-1,1); 59 LL oo = (n-1)*n/2*(n-2)/3; 60 printf("%I64d\n",oo-ans); 61 } 62 return 0; 63 }