洛谷 4149 [IOI2011]Race——点分治
题目:https://www.luogu.org/problemnew/show/P4149
第一道点分治!
点分治大约是每次找重心,以重心为根做一遍树形dp;然后对于该根的每个孩子,递归下去。递归之前把该根的vis设成1,就相当于删掉该点这边的这部分。
对于这道题,要开一个1e6的桶,就不能给每个节点都开了;所以弄一个全局的,在递归给孩子之前都赋成初值就行了。
注意要弄完一个孩子再把它的点的值加到该根的数组里,作为“之前孩子的值”;而且递归之前赋初值memset也比较慢,开一个栈之类的就都好了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+,M=1e6+,INF=0x3f3f3f3f;
int n,K,f[M],hd[N],xnt,to[N<<],w[N<<],nxt[N<<],sta[N][],top;
int siz[N],mn,dis[N],sl[N],ans=N;
bool vis[N];
void add(int x,int y,int z)
{
to[++xnt]=y;nxt[xnt]=hd[x];w[xnt]=z;hd[x]=xnt;
to[++xnt]=x;nxt[xnt]=hd[y];w[xnt]=z;hd[y]=xnt;
}
void getrt(int cr,int fa,int &rt,int s)
{
siz[cr]=;int mx=;
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa)
{
getrt(v,cr,rt,s);siz[cr]+=siz[v];mx=max(mx,siz[v]);
}
mx=max(mx,s-siz[cr]);
if(mx<mn)mn=mx,rt=cr;
}
void dfs(int cr,int fa)
{
siz[cr]=;
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]&&v!=fa)
{
dis[v]=dis[cr]+w[i];sl[v]=sl[cr]+;
if(K>=dis[v])
{
ans=min(ans,sl[v]+f[K-dis[v]]);
sta[++top][]=dis[v];sta[top][]=sl[v];
}
dfs(v,cr);siz[cr]+=siz[v];
}
}
void solve(int cr)
{
vis[cr]=;int p0=;
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]])
{
dis[v]=w[i];sl[v]=;
if(K>=dis[v])
{
ans=min(ans,sl[v]+f[K-dis[v]]);
sta[++top][]=dis[v];sta[top][]=sl[v];
}
dfs(v,);
for(int i=p0;i<=top;i++)f[sta[i][]]=min(f[sta[i][]],sta[i][]);
p0=top+;
}
for(int i=;i<=top;i++)f[sta[i][]]=INF;top=;
for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]])
{
mn=N;int rt;getrt(v,,rt,siz[v]);
solve(rt);
}
}
int main()
{
scanf("%d%d",&n,&K);int x,y,z;
for(int i=;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);x++;y++;add(x,y,z);
}
memset(f,0x3f,sizeof f);f[]=;
mn=N;int rt;getrt(,,rt,n);solve(rt);
printf("%d\n",ans==N?-:ans);
return ;
}
洛谷 4149 [IOI2011]Race——点分治的更多相关文章
- 洛谷$P4149\ [IOI2011]\ Race$ 点分治
正解:点分治 解题报告: 传送门$QwQ$ 昂先不考虑关于那个长度的限制考虑怎么做? 就开个桶,记录所有边的取值,每次加入边的时候查下是否可行就成$QwQ$ 然后现在考虑加入这个长度的限制?就考虑把这 ...
- 模板—点分治B(合并子树)(洛谷P4149 [IOI2011]Race)
洛谷P4149 [IOI2011]Race 点分治作用(目前只知道这个): 求一棵树上满足条件的节点二元组(u,v)个数,比较典型的是求dis(u,v)(dis表示距离)满足条件的(u,v)个数. 算 ...
- 洛谷P4149 [IOI2011]Race(点分治)
题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK ,且边的数量最小. 输入输出格式 输入格式: 第一行:两个整数 n,kn,k . 第二至 nn 行:每行三个整数,表示一条无向边的 ...
- [洛谷P4149][IOI2011]Race
题目大意:给一棵树,每条边有边权.求一条简单路径,权值和等于$K$,且边的数量最小. 题解:点分治,考虑到这是最小值,不满足可减性,于是点分中的更新答案的地方计算重复的部分要做更改,就用一个数组记录前 ...
- 洛谷 P4149 [IOI2011]Race-树分治(点分治,不容斥版)+读入挂-树上求一条路径,权值和等于 K,且边的数量最小
P4149 [IOI2011]Race 题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK,且边的数量最小. 输入格式 第一行包含两个整数 n, Kn,K. 接下来 n - 1n−1 行 ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- 洛谷SP22343 NORMA2 - Norma(分治,前缀和)
洛谷题目传送门 这题推式子恶心..... 考虑分治,每次统计跨过\(mid\)的所有区间的答案和.\(i\)从\(mid-1\)到\(l\)枚举,统计以\(i\)为左端点的所有区间. 我们先维护好\( ...
- bzoj2599/luogu4149 [IOI2011]Race (点分治)
点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...
- [IOI2011]Race 点分治
[IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...
随机推荐
- MATLAB循环结构:while语句P69范数待编
while语句的一般格式为: while 条件 循环体语句 end 从键盘输入若干个数,当输入0时结束输入,求这些数的平均值和它们的和. 程序如下: sum=; n=; x=input('输入一个数字 ...
- vue组件父子组件之间传递数据
举个栗子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- python脚本分析nginx访问日志
日志格式如下: 223.74.135.248 [11/May/2017:11:19:47 +0800] "POST /login/getValidateCode HTTP/1.1" ...
- Residual (numerical analysis)
In many cases, the smallness of the residual means that the approximation is close to the solution, ...
- Orthogonal Least Squares Learning Algorithm for Radial Basis Function Networks
Orthogonal Least Squares Learning Algorithm for Radial Basis Function Networks S. Chen, C. F. N. Cow ...
- linux c编程:信号(三) sigprocmask和sigpending函数
信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如下图所示: 进程可以阻塞信号的传递.当信号源为目标进程产生了一个信号之后,内核会执行依 ...
- Ubuntu 13.04 可以使用的源
以下为收集的Ubuntu 13.04 可以使用的源 #中科大源deb http://mirrors.ustc.edu.cn/ubuntu/ saucy main restricted universe ...
- (转)Javascript模块化编程(二):AMD规范
这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要 ...
- ubuntu安装pip和python
安装pip2sudo apt-get install pip 这样安装的是pip2不支持Python3.x,可以使用如下命令安装pip3 sudo apt-get install python3-pi ...
- Linux基础系列:常用命令(6)_nfs服务与nginx服务
NFS介绍: NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统 ...