题目: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——点分治的更多相关文章

  1. 洛谷$P4149\ [IOI2011]\ Race$ 点分治

    正解:点分治 解题报告: 传送门$QwQ$ 昂先不考虑关于那个长度的限制考虑怎么做? 就开个桶,记录所有边的取值,每次加入边的时候查下是否可行就成$QwQ$ 然后现在考虑加入这个长度的限制?就考虑把这 ...

  2. 模板—点分治B(合并子树)(洛谷P4149 [IOI2011]Race)

    洛谷P4149 [IOI2011]Race 点分治作用(目前只知道这个): 求一棵树上满足条件的节点二元组(u,v)个数,比较典型的是求dis(u,v)(dis表示距离)满足条件的(u,v)个数. 算 ...

  3. 洛谷P4149 [IOI2011]Race(点分治)

    题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK ,且边的数量最小. 输入输出格式 输入格式:   第一行:两个整数 n,kn,k . 第二至 nn 行:每行三个整数,表示一条无向边的 ...

  4. [洛谷P4149][IOI2011]Race

    题目大意:给一棵树,每条边有边权.求一条简单路径,权值和等于$K$,且边的数量最小. 题解:点分治,考虑到这是最小值,不满足可减性,于是点分中的更新答案的地方计算重复的部分要做更改,就用一个数组记录前 ...

  5. 洛谷 P4149 [IOI2011]Race-树分治(点分治,不容斥版)+读入挂-树上求一条路径,权值和等于 K,且边的数量最小

    P4149 [IOI2011]Race 题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK,且边的数量最小. 输入格式 第一行包含两个整数 n, Kn,K. 接下来 n - 1n−1 行 ...

  6. BZOJ 2599: [IOI2011]Race( 点分治 )

    数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...

  7. 洛谷SP22343 NORMA2 - Norma(分治,前缀和)

    洛谷题目传送门 这题推式子恶心..... 考虑分治,每次统计跨过\(mid\)的所有区间的答案和.\(i\)从\(mid-1\)到\(l\)枚举,统计以\(i\)为左端点的所有区间. 我们先维护好\( ...

  8. bzoj2599/luogu4149 [IOI2011]Race (点分治)

    点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...

  9. [IOI2011]Race 点分治

    [IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...

随机推荐

  1. [原创]使用vscode+es6写nodejs服务端调试配置

    前端的小伙伴们在babel等的加持下,已经可以愉快的使用es6来写代码了. 然后对于服务端的nodejs就有点坑爹了,虽然原生支持了es6,但是只是部分支持,一些不支持的特性(比如module)使用了 ...

  2. zoj 3721 Final Exam Arrangement【贪心】

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3721 来源:http://acm.hust.edu.cn/vjudg ...

  3. 测试站如何最快获取正式站的最新数据: ln -s

    针对静态数据, 比如图片/js等文件, 测试站如何获取最新的呢? ln -s /alidata/www/mysite/uploads /alidata/www/mysite_test/uploads ...

  4. jmeter--基于http+json接口的功能测试

    jmeter--基于http+json接口的功能测试 测试项目叫做smile_task,简称sm_task.这是一个基于nodejs超简单的todo list,sm_task没有任何UI界面(纯接口) ...

  5. Python菜鸟之路:Python基础——函数

    一.函数 1. 简介 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 2. 组成 函数代码块以 def 关键词开头,后接函数名和圆括号( ...

  6. linux c编程:信号(二) alarm和pause函数

    使用alarm函数可以设置一个定时器,在将来的某个时刻该定时器超时.当定时器超时后,产生SIGALRM信号.如果忽略或不捕捉此信号,则其默认动作是终止调用该alarm函数的进程 #include< ...

  7. JQuery日记 5.11 Sizzle选择器(五)

    //设置当前document和document相应的变量和方法 setDocument = Sizzle.setDocument = function( node ) { var hasCompare ...

  8. oc中的blocks的功能,一种比代理简洁的方式

    blocks方式: 谁要东西谁就要写blocks,通过blocks(返回值)获取想要的,提供东西的人要通过实现函数指针把东西给想要的人.当然也可以传值,传值需要通过形参. block的功能: bloc ...

  9. Hive2.0的新特性介绍

  10. Python OOP(1)

    类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外. ...