Y
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2762 Accepted Submission(s): 800
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
可以先找到三个点的SIMPLE-PATH的数量,然后让C(N,3)-SIMPLE-PATH就是答案了。
对于节点u,子树的节点个数为n1,n2,,,,,nk的话,以u为中点的SIMPLE-PATH的数量就是n1(n2+n3+...+nk)+n2(n3+...+nk)+.....+nk-1*nk,这一步可以在遍历儿子时迭代实现。
别忘记还有一颗子树是父亲节点,N-sum[u].
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #pragma comment(linker, "/STACK:16777216") 7 #define LL long long 8 vector<int>g[100005]; 9 LL sum[100005]; 10 LL tot,N; 11 void dfs(int u,int pre){ 12 sum[u]=1; 13 LL res=0; 14 for(int i=0;i<g[u].size();++i){ 15 if(g[u][i]==pre) continue; 16 dfs(g[u][i],u); 17 sum[u]+=sum[g[u][i]]; 18 tot+=res*sum[g[u][i]]; 19 res+=sum[g[u][i]]; 20 } 21 tot+=res*(N-sum[u]); 22 } 23 int main() 24 { 25 while(cin>>N){int u,v; 26 tot=0; 27 for(int i=1;i<N;++i){ 28 scanf("%d%d",&u,&v); 29 g[u].push_back(v); 30 g[v].push_back(u); 31 } 32 dfs(1,0); 33 LL tt=0; 34 LL ans=N*(N-1)*(N-2)/6; 35 cout<<ans-tot<<endl; 36 for(int i=1;i<=N;++i) g[i].clear(); 37 } 38 return 0; 39 }