hdu 4705 Y(树形DP)
题目链接:hdu 4705 Y
题意:
给你一棵n个节点的树,问你不在同一条路径上的三点对的对数。
题解:
n个节点任选三个点Cn3 ,然后我们可以dp出在同一条路径上的三点对,然后减一减
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #pragma comment(linker, "/STACK:16777216") 3 #define F(i,a,b) for(int i=a;i<=b;i++) 4 using namespace std; 5 typedef long long ll; 6 7 const int N=1e5+7; 8 int n,g[N],v[2*N],nxt[N*2],ed,x,y,sz[N]; 9 ll ans; 10 11 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} 12 13 void dfs(int x,int fa) 14 { 15 sz[x]=1; 16 for(int i=g[x];i;i=nxt[i]) 17 if(v[i]!=fa)dfs(v[i],x),sz[x]+=sz[v[i]]; 18 } 19 20 void dfs2(int x,int fa) 21 { 22 for(int i=g[x];i;i=nxt[i]) 23 if(v[i]!=fa)ans+=1ll*sz[v[i]]*(sz[x]-1-sz[v[i]]); 24 } 25 26 int main() 27 { 28 while(~scanf("%d",&n)) 29 { 30 ed=0; 31 F(i,1,n)g[i]=0; 32 F(i,1,n-1)scanf("%d%d",&x,&y),adg(x,y),adg(y,x); 33 ans=0,dfs(1,0),dfs2(1,0); 34 printf("%lld\n",1ll*n*(n-1)*(n-2)/6-ans/2); 35 } 36 return 0; 37 }