3522: [Poi2014]Hotel

3522: [Poi2014]Hotel

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 253  Solved: 117
[Submit][Status][Discuss]

Description

有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达。吉丽要给他的三个妹子各开(一个)房(间)。三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽满意,你需要让三个房间两两距离相同。
有多少种方案能让吉丽满意?

Input

第一行一个数n。
接下来n-1行,每行两个数x,y,表示x和y之间有一条边相连。

Output

让吉丽满意的方案数。

Sample Input

7
1 2
5 7
2 5
2 3
5 6
4 5

Sample Output

5

HINT

【样例解释】

{1,3,5},{2,4,6},{2,4,7},{2,6,7},{4,6,7}

【数据范围】

n≤5000

Source

By Dzy

题解:其实我感觉这个题更像是一个树状DP,可是想了半天似乎总是难以处理顶上的距离相等节点的问题(树状DP难免要把无根树用有根树的方式处理,这样子问题就来了)

其实正如很多网上的题解所言,枚举出每一个核心点(也就是三个点到此点距离相等,且三点来自核心点的不同子树上),然后根据外部各个子树的各个深度的点的统计,来计算出可能性的数量

于是这个里面涉及到对于一大堆数,怎样快速求出不同的数三三相乘的总和,比如(1,2,3,4),要求的就是1×2×3+1×2×4+1×3×4+2×3×4=50

其实这个东西可以仿照快速求出两两乘机和的办法——用O(n)的时间扫一遍,求出和,平方和,立方和,然后直接根据这三个数可以直接推出来—— \(\sum = {\frac{ {A_1}^{3}-3 A_2 A_1 +2 A_3}{6}}\)

然后别的没了,上代码

  1 /**************************************************************
  2     Problem: 3522
  3     User: HansBug
  4     Language: Pascal
  5     Result: Accepted
  6     Time:7828 ms
  7     Memory:3316 kb
  8 ****************************************************************/
  9
 10 type
 11     point=^node;
 12     node=record
 13                g,w:longint;
 14                next:point;
 15     end;
 16     map=array[0..20000] of point;
 17 var
 18    i,j,k,l,m,n:longint;
 19    a,c:map;
 20    b:array[0..20000] of int64;
 21    d,e,f,g:array[0..20000] of longint;
 22    p:point;
 23    ans:int64;
 24 procedure add(x,y,z:longint;var a:map);
 25           var p:point;
 26           begin
 27                new(p);p^.g:=y;p^.w:=z;
 28                p^.next:=a[x];a[x]:=p;
 29           end;
 30 function cal:int64;
 31          var i:longint;a1,a2,a3:int64;
 32          begin
 33               a1:=0;a2:=0;a3:=0;
 34               if b[0]<3 then exit(0);
 35               for i:=1 to b[0] do
 36                   begin
 37                        a1:=a1+b[i];
 38                        a2:=a2+b[i]*b[i];
 39                        a3:=a3+b[i]*b[i]*b[i];
 40                   end;
 41               exit((a1*a1*a1-3*a1*a2+2*a3) div 6);
 42          end;
 43 procedure dfs(x,y:longint);
 44           var p:point;
 45           begin
 46                p:=a[x];g[x]:=1;
 47                while p<>nil do
 48                      begin
 49                           if g[p^.g]=0 then
 50                              begin
 51                                   inc(d[y+1]);
 52                                   dfs(p^.g,y+1);
 53                              end;
 54                           p:=p^.next;
 55                      end;
 56           end;
 57 begin
 58      readln(n);
 59      for i:=1 to n do a[i]:=nil;
 60      for i:=1 to n-1 do
 61          begin
 62               readln(j,k);
 63               add(j,k,1,a);add(k,j,1,a);
 64          end;
 65      ans:=0;
 66      for i:=1 to n do
 67          begin
 68               p:=a[i];
 69               for j:=1 to n do c[j]:=nil;
 70               fillchar(g,sizeof(g),0);
 71               g[i]:=1;
 72               while p<>nil do
 73                     begin
 74                          fillchar(d,sizeof(d),0);
 75                          d[1]:=1;
 76                          dfs(p^.g,1);
 77                          for j:=1 to n do
 78                              begin
 79                                   if d[j]=0 then break;
 80                                   add(j,d[j],0,c);
 81                              end;
 82                          p:=p^.next;
 83                     end;
 84               for j:=1 to n do
 85                   begin
 86                        b[0]:=0;
 87                        p:=c[j];
 88                        while p<>nil do
 89                              begin
 90                                   inc(b[0]);
 91                                   b[b[0]]:=p^.g;
 92                                   p:=p^.next;
 93                              end;
 94                        inc(ans,cal);
 95                   end;
 96
 97               j:=0;
 98          end;
 99      writeln(ans);
100      readln;
101 end.                      
时间: 2024-10-12 11:47:10

3522: [Poi2014]Hotel的相关文章

3522: [Poi2014]Hotel( 树形dp )

枚举中点x( 即选出的三个点 a , b , c 满足 dist( x , a ) = dist( x , b ) = dist( x , c ) ) , 然后以 x 为 root 做 dfs , 显然两个位于 x 的同一颗子树内的点是不可能被同时选到的 . 我们对 x 的每一颗子树进行 dfs , 记录下当前子树中的点到 x 距离为 d ( 1 <= d <= n ) 有多少个 , 记为 cnt[ 0 ][ i ] . 然后 cnt[ 1 ][ i ] 记录之前 dfs 过的子树的 cnt[

bzoj 3522: [Poi2014]Hotel

呵呵,一开始天真的我以为求个 西格玛 C(??,3)就好了.. (题解:比枚举2个数的再多一个,,一样搞) 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define lowbit(x) x&(-x) 4 #define inf 1e15 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'

BZOJ 3522 [Poi2014] Hotel 题解

题意:求一棵边权全都是1的树上,集合大小为3,且集合内点两两距离相等的集合个数. NOIP2014 D1T2加强版.. 通过分析发现,满足这样的点对一定是在有根树中深度相同,且不再同一棵以根节点儿子为根的子树中. 于是我们枚举根.. 三个点的集合个数是由2个点的集合个数转移过来的..2个又是由一个转移过来的.用两个数组保存一下即可. 1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include&

BZOJ3522——[Poi2014]Hotel

1.题意:http://www.lydsy.com/JudgeOnline/problem.php?id=3522 2.分析:这道题有两种情况,第一个是三个点在同一个链上,这显然不可能了,因为树上的路径是唯一的,第二个情况是三个点距离某个中心的距离相等 那么我们只需枚举中间点,然后在不同子树中dfs一下即可求出答案 #include <queue> #include <cstdio> #include <cstring> #include <cstdlib>

@bzoj - [email&#160;protected] [POI2014]Hotel加强版

目录 @[email protected] @[email protected] @part - [email protected] @part - [email protected] @accepted [email protected] @[email protected] @[email protected] 给定一棵树,求无序三元组 (a, b, c) 的个数,使得 dis(a, b) = dis(b, c) = dis(c, a),且 a ≠ b, b ≠ c, c ≠ a. inpu

bzoj3522 [Poi2014]Hotel

题目链接 在黄学长博客上居然分类树形DP? 暴力,以每个点为根计算子树内答案,推推式子就维护两个S就可以啦 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime&

【bzoj3522】[Poi2014]Hotel 树形dp

题目描述 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房(间).三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽满意,你需要让三个房间两两距离相同.有多少种方案能让吉丽满意? 输入 第一行一个数n.接下来n-1行,每行两个数x,y,表示x和y之间有一条边相连. 输出 让吉丽满意的方案数. 样例输入 7 1 2 5 7 2 5 2 3 5 6 4 5 样例输出 5 题解 树形dp 如果树上三个点之间两两距离相同

[Poi2014]Hotel

Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房(间).三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽满意,你需要让三个房间两两距离相同. 有多少种方案能让吉丽满意? Input 第一行一个数n. 接下来n-1行,每行两个数x,y,表示x和y之间有一条边相连. Output 让吉丽满意的方案数. Sample Input 7 1 2 5 7 2 5 2 3 5 6 4 5 Sample

[Poi2014][BZOJ3522] Hotel

3522: [Poi2014]Hotel Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 278  Solved: 136[Submit][Status][Discuss] Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房(间).三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽满意,你需要让三个房间两两距离相同.有多少种方案能让吉丽满意?