hdu4705Y

链接

这题可以算树形DP吧 树上的递推

对于树上的某个节点 反着算比较好做 就是算有多少有simple路径的

固定某个节点u 另两个节点 有两种取法

1.从不同子树里各选一个

2.从所有子树里选一个 再从以u为跟的子树 外面选一个

求总和

 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 }
View Code

 

posted @ 2013-08-25 21:35  _雨  阅读(193)  评论(0编辑  收藏  举报