Y
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Problem Description
Sample Input
4
1 2
1 3
1 4
Sample Output
1
Hint
1. The only set is {2,3,4}.
2. Please use #pragma comment(linker, "/STACK:16777216")
Source
思路:反面考虑,用总的方案数减去A,B,C三点在同一路径上的方案数。
确定中间点B,在当前以B为根求得的son中任选一个,在剩下的节点n-all_son-1(all_son为已经求得的B的儿子的个数)中任选一个,构成son*(n-all_son-1)种组合。
另外,手动扩栈(递归的层数太大,以至于爆栈,就需要把栈扩大些),C++提交。
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <map> #include <vector> #include <set> #include <algorithm> #include <vector> #include <stack> #include <math.h> #include <stdlib.h> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #pragma comment(linker, "/STACK:16777216") using namespace std; typedef long long LL ; const int size=100008 ; int vec[size] ; bool visited[size] ; struct Me{ struct Edge{ int v ; int next ; }; LL N ; int id ; LL sum ; Edge edge[2*size] ; Me(){} ; Me(int n):N(n){ id=0 ; sum=0 ; memset(vec,-1,sizeof(vec)) ; memset(visited,0,sizeof(visited)) ; } void add_edge(int u ,int v){ edge[id].v=v ; edge[id].next=vec[u] ; vec[u]=id++ ; } LL dfs(int u){ visited[u]=1 ; LL all_son=0 ; for(int e=vec[u];e!=-1;e=edge[e].next){ int v=edge[e].v ; if(visited[v]) continue ; LL son=dfs(v) ; all_son+=son ; sum+=(N-all_son-1)*son ; } return all_son+1 ; } LL gao(){ int u ,v ; for(int i=1;i<N;i++){ scanf("%d%d",&u,&v) ; add_edge(u,v) ; add_edge(v,u) ; } dfs(1) ; return N*(N-1)*(N-2)/6-sum ; } }; int main(){ LL n ; while(cin>>n){ Me me(n); cout<<me.gao()<<endl ; } return 0 ; }