[bzoj3522] [Poi2014]Hotel

  枚举一个点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\n",ans);
44 }
View Code

 

posted @ 2016-06-18 16:04  czllgzmzl  阅读(202)  评论(0编辑  收藏  举报