题目: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. 鼠标画矩形openCV

    #include <cv.h> #include <highgui.h> #include <stdio.h> /*鼠标画矩形*/ void my_mouse_ca ...

  2. Java程序发送邮件

    之前上网有看到过别人总结的使用java程序发送邮件,于是自己下来练习,把自己学习的一些心得总结出来. 首先我们这里需要采用两个jar包: 需要的朋友可以自行上网去CSDN类似的网站上面找 顺便把自己测 ...

  3. Arrays类--Arrays.asList()方法使用

    java.util类 Arrays java.lang.Object——java.util.Arrays public class Arrays extends Object 此类包含用来操作数组(比 ...

  4. Every norm is a convex function

    https://ipfs.io/ipfs/QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco/wiki/Convex_function.html Every  ...

  5. 解决pod没有权限问题

    chmod 644 路径 echo $? 检测上一条命令的执行结果,如果是0则执行成功

  6. Gateway

    网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连.网关的结构也和路由器类似,不同的是互连层.网关既可以用于广域网互连,也可以用于局域网互连. 网关是一种充当转换重 ...

  7. java程序实现Unicode码和中文互相转换

      根据前一篇的补充问题http://blog.csdn.net/fancylovejava/article/details/10142391 有了前一篇文章的了解,大概了解了unicode编码格式了 ...

  8. inline-block间距解决方案

    当我们将元素设为inline-block时,总是会莫名其妙出现一些间距 <!DOCTYPE html> <html> <head> <meta charset ...

  9. 【DP】最长不下降子序列问题(二分)

    Description 给你一个长度为n的整数序列,按从左往右的顺序选择尽量多的数字并且满足这些数字不下降. Thinking 朴素dp算法:F[i]表示到第i位为止的最长不下降子序列长度 F[i]= ...

  10. scp的用法

    scp是有Security的文件copy,基于ssh登录.命令基本格式:scp [OPTIONS] file_source file_target OPTIONS:-v 和大多数 linux 命令中的 ...