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 ;
}
浙公网安备 33010602011771号