【刷题】BZOJ 3522 [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 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的更多相关文章
- BZOJ.3522.[POI2014]Hotel(DP)
题目链接 BZOJ 洛谷 以为裸点分治,但数据范围怎么这么小?快打完了发现不对.. n^2做的话其实是个水题.. 枚举每一个点为根,为了不重复计算,我们要求所求的三个点必须分别位于三棵子树上. 考虑当 ...
- bzoj 3522: [Poi2014]Hotel
呵呵,一开始天真的我以为求个 西格玛 C(??,3)就好了.. (题解:比枚举2个数的再多一个,,一样搞) #include <bits/stdc++.h> #define LL long ...
- 【刷题】BZOJ 4543 [POI2014]Hotel加强版
Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...
- 3522: [Poi2014]Hotel
3522: [Poi2014]Hotel Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 253 Solved: 117[Submit][Status ...
- 3522: [Poi2014]Hotel( 树形dp )
枚举中点x( 即选出的三个点 a , b , c 满足 dist( x , a ) = dist( x , b ) = dist( x , c ) ) , 然后以 x 为 root 做 dfs , 显 ...
- BZOJ.4543.[POI2014]Hotel加强版(长链剖分 树形DP)
题目链接 弱化版:https://www.cnblogs.com/SovietPower/p/8663817.html. 令\(f[x][i]\)表示\(x\)的子树中深度为\(i\)的点的个数,\( ...
- bzoj 4543: [POI2014]Hotel加强版
Description 给出一棵树求三元组 \((x,y,z)\,,x<y<z\) 满足三个点两两之间距离相等,求三元组的数量 Solution 考虑暴力 \(DP\) 设 \(f[i][ ...
- ZJOI2019一轮停课刷题记录
Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...
- BZOJ3522: [Poi2014]Hotel
3522: [Poi2014]Hotel Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 195 Solved: 85[Submit][Status] ...
随机推荐
- lwip lwiperf 方法进行性能测试 4.5MB/S
硬件配置: STM32F407 + DP83848 + FreeRTOS V10.1.1 + LWIP 2.1.2 2018年12月5日14:31:24 1.先读取 PHY 寄存器 , 查看 自 ...
- 20155216 Exp3 免杀原理与实践
Exp3 免杀原理与实践 基于特征码的改变来实现免杀(实践过程记录) MSF编码器编译后门检测 可以通过VirSCAN来检验后门抗杀能力. ps:选择后门前修改其文件名,不得含有数字. 如上图所示,3 ...
- Vue 使用细节收集
JSX 中 on 开头的属性名 在用 elementui 中的 el-upload 的时候,他们组件中有一个属性 on-change ,也不知道谁想出来的属性名,太扯淡了,非要 on 开头,我开始的代 ...
- flask登录注册简单的例子
1.主程序 # app.py # Auther: hhh5460 # Time: 2018/10/05 # Address: DongGuan YueHua from functools import ...
- linux 定时器原理
内核定时器: unsigned long timeout = jiffies + (x * HZ); while(1) { // Check the condition. ...
- Selenium之前世今生
前世 Selenium RC 早期的Selenium使用的是JavaScript注入技术与浏览器打交道,需要Selenium RC启动一个Server,将操作Web元素的API调用转化为一段段Java ...
- 封装之property,多态,鸭子类型,classmethod与staticmethod
一.封装之Property prooerty是一种特殊的属性,访问时他会执行一段功能(函数)然后返回 '''BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属 ...
- SSISDB6:参数和环境变量
SSISDB 系列随笔汇总: SSISDB1:使用SSISDB管理Package SSISDB2:SSIS工程的操作实例 SSISDB3:Package的执行实例 SSISDB4:当前正在运行的Pac ...
- effective c++ 笔记 (35-40)
//---------------------------15/04/24---------------------------- //#35 考虑virtual函数以外的其他选择 { /* 1: ...
- Seay源代码审计系统的配置和安装
2014年7月31日 Seay源代码审计系统2.1 时隔刚好一年之久,源代码审计系统再次更新,这次主要优化审计体验,优化了漏洞规则,算是小幅更新,原来使用者打开程序会提示自动更新. 1.优化原有规则, ...