枚举一个点rt作为三个房间的中点。
那三个房间肯定在rt的不同子树内,且深度相同。
f1[i],f2[i],f3[i]分别表示深度为i,取1,2,3个点的方案数。
时间复杂度O(n^2)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define ll long long 6 using namespace std; 7 const int maxn=5023; 8 struct zs{int too,pre,dis;}e[maxn<<1];int tot,last[maxn]; 9 ll f3[maxn],ans; 10 int f2[maxn],f1[maxn],s[maxn],t,st[maxn],top; 11 int i,j,k,n,m; 12 13 int ra;char rx; 14 inline int read(){ 15 rx=getchar(),ra=0; 16 while(rx<'0'||rx>'9')rx=getchar(); 17 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 18 } 19 inline void insert(int a,int b){ 20 e[++tot].too=b,e[tot].pre=last[a],last[a]=tot, 21 e[++tot].too=a,e[tot].pre=last[b],last[b]=tot; 22 } 23 void dfs(int x,int fa,int dis){ 24 s[++t]=dis; 25 for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa)dfs(e[i].too,x,dis+1); 26 } 27 int main(){ 28 n=read();register int k; 29 for(i=1;i<n;i++)insert(read(),read()); 30 for(i=1;i<=n;i++){ 31 top=0; 32 for(j=last[i];j;j=e[j].pre)st[++top]=e[j].too; 33 if(top<3)continue; 34 for(j=1;j<=top;j++){ 35 t=0,dfs(st[j],i,1); 36 for(k=1;k<=t;k++)f3[s[k]]+=f2[s[k]]; 37 for(k=1;k<=t;k++)f2[s[k]]+=f1[s[k]]; 38 for(k=1;k<=t;k++)f1[s[k]]++; 39 } 40 for(j=1;j<n;j++)ans+=f3[j]; 41 memset(f1,0,n<<2),memset(f2,0,n<<2),memset(f3,0,n<<3); 42 } 43 printf("%lld ",ans); 44 }