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

Solution

先写了个普通的方法,

就是枚举每一个点,计算这个点为选的三个点的lca的方案数

这个只要在枚举了lca后遍历它的每个子树,当前子树内的一个点可以贡献之前的子树中深度与它相同的点中选两个的方案数,处理一下就好了

以下代码是可以过的:

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=5000+10;
int n,e,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],sum[MAXN];
ll ans,val[2][MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void dfs(int x,int f,int dep)
{
ans+=val[1][dep],sum[dep]++;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==f)continue;
else dfs(to[i],x,dep+1);
}
int main()
{
read(n);
for(register int i=1;i<n;++i)
{
int u,v;read(u);read(v);
insert(u,v);insert(v,u);
}
for(register int i=1;i<=n;++i)
{
for(register int j=beg[i];j;j=nex[j])
{
dfs(to[j],i,1);
for(register int j=1;j<=n;++j)val[1][j]+=val[0][j]*sum[j],val[0][j]+=sum[j],sum[j]=0;
}
for(register int j=1;j<=n;++j)val[0][j]=val[1][j]=0;
}
write(ans,'\n');
return 0;
}

之后为了做升级版,写了个没用长链剖分的 \(O(n^2)\) dp,也是当做一个过渡吧

设 \(f[u][k]\) 表示 \(u\) 的子树中距离 \(u\) 为 \(k\) 的点的个数, \(g[u][k]\) 表示 \(u\) 的子树中到LCA距离为 \(d\) ,\(u\) 到LCA距离为 \(d−k\) 的点对的数量。

转移就见程序吧,因为转移的顺序是对转移有影响的

这个程序被卡空间了,过不去,但是正确性是能够保证的:

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=5000+10;
int n,e,beg[MAXN],nex[MAXN<<1],to[MAXN<<1];
ll f[MAXN][MAXN],g[MAXN][MAXN],ans;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void dfs(int x,int p)
{
f[x][0]=1;
for(register int i=beg[x];i;i=nex[i])
if(to[i]==p)continue;
else
{
dfs(to[i],x);
for(register int j=0;j<=n;++j)
{
ans+=f[x][j]*g[to[i]][j+1]+(j?f[to[i]][j-1]*g[x][j]:0);
g[x][j]+=g[to[i]][j+1]+(j?f[x][j]*f[to[i]][j-1]:0);
if(j)f[x][j]+=f[to[i]][j-1];
}
}
}
int main()
{
read(n);
for(register int i=1;i<n;++i)
{
int u,v;read(u);read(v);
insert(u,v);insert(v,u);
}
dfs(1,0);
write(ans,'\n');
return 0;
}

【刷题】BZOJ 3522 [Poi2014]Hotel的更多相关文章

  1. BZOJ.3522.[POI2014]Hotel(DP)

    题目链接 BZOJ 洛谷 以为裸点分治,但数据范围怎么这么小?快打完了发现不对.. n^2做的话其实是个水题.. 枚举每一个点为根,为了不重复计算,我们要求所求的三个点必须分别位于三棵子树上. 考虑当 ...

  2. bzoj 3522: [Poi2014]Hotel

    呵呵,一开始天真的我以为求个 西格玛 C(??,3)就好了.. (题解:比枚举2个数的再多一个,,一样搞) #include <bits/stdc++.h> #define LL long ...

  3. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  4. 3522: [Poi2014]Hotel

    3522: [Poi2014]Hotel Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 253  Solved: 117[Submit][Status ...

  5. 3522: [Poi2014]Hotel( 树形dp )

    枚举中点x( 即选出的三个点 a , b , c 满足 dist( x , a ) = dist( x , b ) = dist( x , c ) ) , 然后以 x 为 root 做 dfs , 显 ...

  6. BZOJ.4543.[POI2014]Hotel加强版(长链剖分 树形DP)

    题目链接 弱化版:https://www.cnblogs.com/SovietPower/p/8663817.html. 令\(f[x][i]\)表示\(x\)的子树中深度为\(i\)的点的个数,\( ...

  7. bzoj 4543: [POI2014]Hotel加强版

    Description 给出一棵树求三元组 \((x,y,z)\,,x<y<z\) 满足三个点两两之间距离相等,求三元组的数量 Solution 考虑暴力 \(DP\) 设 \(f[i][ ...

  8. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

  9. BZOJ3522: [Poi2014]Hotel

    3522: [Poi2014]Hotel Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 195  Solved: 85[Submit][Status] ...

随机推荐

  1. URL最大长度

    今天在测试Email Ticket的时候发现在进行Mark as Read/Unread操作时,请求是通过GET方式进行的.URL中列出了所有参与该操作的Ticket Id.于是,我想起GET请求是有 ...

  2. 20155311《网络对抗》PC平台逆向破解(二)

    20155311<网络对抗>PC平台逆向破解(二) shellcode注入 什么是shellcode? shellcode是一段代码,溢出后,执行这段代码能开启系统shell. 前期准备- ...

  3. maven中添加jetty运行插件

            maven项目,用jetty插件运行,对热部署的支持比较好.maven的pom文件加入下面代码 <plugin> <groupId>org.mortbay.je ...

  4. SQLAlchemy 与 fask-SQLAlchemy 中的多表查询例子

    我们知道,<学生.课程.选课>,是一个典型的多对多关系. 现分别用 SQLAlchemy 与 fask-SQLAlchemy 实现. 声明:本人实测通过. 使用 SQLAlchemy fr ...

  5. 带阴影的圆形 QLabel

    带阴影的圆形 Label 来自: 公孙二狗

  6. cocos2d-x学习记录3——CCTouch触摸响应

    游戏不同于影音,强交互性是其一大特色,在游戏中主要体现为接受用户的输入并响应.智能手机触摸是其重要的输入方式. 在cocos2d-x中,触摸分为单点触摸和多点触摸. 单点触摸:主要继承CCTarget ...

  7. spring boot 实现文件下载

    html 代码 js部分 window.location.href= this.Baseurl+'/plan/down?file='+filename; spring boot 后台代码@GetMap ...

  8. Js_特效

    事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture();  event.srcE ...

  9. ansible自动化工具安装和简单使用

    ansible自动化工具安装和简单使用 1.安装 ansible依赖于Python 2.6或更高的版本.paramiko.PyYAML及Jinja2. 2.1 编译安装 解决依赖关系 # yum -y ...

  10. Docker-安装(CentOS7)

    1.安装需要的软件包:yum-util提供yum-config-manager功能 yum install -y yum-utils device-mapper-persistent-data lvm ...