T1 HOTEL
题目大意:
在树上选出三个点使这三个两两之间距离相等 求选出这三个点的方案
思路:
树形dp
枚举每一个树根 选三个和选两个差不多 多开一个dp数组
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<set> 10 #define MAXN 5010 11 #define ll long long 12 #define inf 2139062143 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,fst[MAXN],to[MAXN<<1],nxt[MAXN<<1],cnt,dep[MAXN]; 22 ll tmp[MAXN],dp[MAXN][2],ans; 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 24 void dfs(int x,int fa) 25 { 26 tmp[dep[x]]++; 27 for(int i=fst[x];i;i=nxt[i]) 28 if(to[i]!=fa) {dep[to[i]]=dep[x]+1;dfs(to[i],x);} 29 } 30 int main() 31 { 32 n=read();int a,b; 33 for(int i=1;i<n;i++){a=read(),b=read();add(a,b);add(b,a);} 34 for(int x=1;x<=n;x++) 35 { 36 memset(dp,0,sizeof(dp)); 37 for(int i=fst[x];i;i=nxt[i]) 38 { 39 dep[to[i]]=1;dfs(to[i],x); 40 for(int j=1;j<=n;j++) 41 ans+=dp[j][0]*tmp[j],dp[j][0]+=dp[j][1]*tmp[j],dp[j][1]+=tmp[j]; 42 memset(tmp,0,sizeof(tmp)); 43 } 44 } 45 printf("%lld",ans); 46 }