Luogu 4149 Race
Luogu 4149 Race
- 用点分治解决.
- 点分治在计算路径贡献时,为了不统计在一颗子树中的路径,解决方法一种是容斥,但在这种求最值问题中不便用容斥来撤销.
- 另一种则是,处理一颗子树时,只考虑前面的子树中产生的贡献,而将当前的子树的节点暂时存储在一个栈中,当前子树处理完毕后,再让栈中的点产生贡献,就可以解决求最值等容斥难以处理的问题.
- 就本题而言,记 \(tmp[i]\) 表示路径长度为 \(i\) 的路径中最少的边数.那么每条路径就可以更新答案 \(ans=\min\{ans,edges+tmp[k-len]\}\).将当前子树的点存入 \(s2\) 中,处理完后再用 \(s2\) 内的路径更新 \(tmp\).
- \(tmp\) 每次要初始化为 \(inf\) ,为了避免每次遍历所有点,可以记录哪些位置被修改过(记录在 \(s1\) 中),只用给它们赋值就可以了.
#include<bits/stdc++.h>
#define mp make_pair
#define inf 1e9
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
fh=-1,jp=getchar();
while (jp>='0'&&jp<='9')
out=out*10+jp-'0',jp=getchar();
return out*fh;
}
const int MAXN=2e5+10;
int ans=inf;
int cnt=0,head[MAXN],to[MAXN<<1],nx[MAXN<<1],val[MAXN<<1];
inline void addedge(int u,int v,int w)
{
++cnt;
to[cnt]=v;
nx[cnt]=head[u];
val[cnt]=w;
head[u]=cnt;
}
int n,k;
int vis[MAXN];
int totsiz,sonsiz[MAXN],siz[MAXN],mi,rt;
void findrt(int u,int fa)
{
siz[u]=1;
sonsiz[u]=0;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v==fa || vis[v])
continue;
findrt(v,u);
siz[u]+=siz[v];
sonsiz[u]=max(sonsiz[u],siz[v]);
}
sonsiz[u]=max(sonsiz[u],totsiz-siz[u]);
if(sonsiz[u]<mi)
mi=sonsiz[u],rt=u;
}
int len[MAXN],edges[MAXN];
int tmp[1000000+10];
int s1[MAXN],s2[MAXN];
int tp1,tp2;
void getdis(int u,int fa)
{
if(k>=len[u])
ans=min(ans,edges[u]+tmp[k-len[u]]);
s2[++tp2]=u;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v==fa || vis[v])
continue;
len[v]=len[u]+val[i];
// assert(len[v]<=1000000);
edges[v]=edges[u]+1;
getdis(v,u);
}
}
void solve(int u)
{
len[u]=edges[u]=0;
for(int i=1;i<=tp1;++i)
tmp[s1[i]]=inf;
s1[tp1=1]=u;
tmp[0]=0;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(vis[v])
continue;
tp2=0;
len[v]=val[i],edges[v]=1;
getdis(v,u);
for(int j=1;j<=tp2;++j)
{
v=s2[j];
tmp[len[v]]=min(tmp[len[v]],edges[v]);
s1[++tp1]=len[v];
}
}
}
void divide(int u)
{
solve(u);
vis[u]=1;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(vis[v])
continue;
mi=inf,totsiz=siz[v];
findrt(v,0);
divide(rt);
}
}
int main()
{
// freopen("testdata.in","r",stdin);
n=read(),k=read();
for(int i=1;i<n;++i)
{
int u=read()+1,v=read()+1,w=read();
addedge(u,v,w);
addedge(v,u,w);
}
for(int i=0;i<=1000000;++i)
tmp[i]=inf;
mi=inf,totsiz=n;
findrt(1,0);
divide(rt);
cout<<(ans==inf?-1:ans)<<endl;
return 0;
}
Luogu 4149 Race的更多相关文章
- [LUOGU] 4149 [IOI2011]Race
点分治裸题 #include<iostream> #include<cstring> #include<cstdio> using namespace std; i ...
- 洛谷 4149 [IOI2011]Race——点分治
题目:https://www.luogu.org/problemnew/show/P4149 第一道点分治! 点分治大约是每次找重心,以重心为根做一遍树形dp:然后对于该根的每个孩子,递归下去.递归之 ...
- 【Luogu P4149】[IOI2011]Race(点分治)
自闭了几天后的我终于开始做题了..然后调了3h一道点分治板子题,调了一天一道IOI... 最后还是自己手造数据debug出来的... 这题一看:树上路径问题,已知路径长度求balabala,显然是点分 ...
- 【洛谷4149】[IOI2011] Race(点分治)
点此看题面 大致题意: 给你一棵树,问长度为\(K\)的路径至少由几条边构成. 点分治 这题应该比较显然是点分治. 主要思路 与常见的点分治套路一样,由于\(K≤1000000\),因此我们可以考虑开 ...
- LUOGU P4149 [IOI2011]Race
题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KKK ,且边的数量最小. 输入输出格式 输入格式: 第一行:两个整数 n,kn,kn,k . 第二至 nnn 行:每行三个整数,表示一条无 ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- Promise.race
[Promise.race] 返回最先完成的promise var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 5 ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- golang中的race检测
golang中的race检测 由于golang中的go是非常方便的,加上函数又非常容易隐藏go. 所以很多时候,当我们写出一个程序的时候,我们并不知道这个程序在并发情况下会不会出现什么问题. 所以在本 ...
随机推荐
- Python学习札记(一) 初始python
参考: 廖雪峰教程:Python简介 笔记 1.C语言是可以用来编写操作系统的贴近硬件的语言,所以,C语言适合开发那些追求运行速度.充分发挥硬件性能的程序.而Python是用来编写应用程序的高级编程语 ...
- Android开发-网络通信2
调试了三种通信方法:HttpClient.AsyncHttpClient 和 Volley . HttpClient 测试代码[1]: public class HttpUtil { public s ...
- java工具类使用
ResourceBundle bundle = ResourceBundle.getBundle("res", new Locale("zh", "C ...
- LeetCode第[73]题(Java):Set Matrix Zeroes(矩阵置0)
题目:矩阵置0 难度:Easy 题目内容: Given a m x n matrix, if an element is 0, set its entire row and column to 0. ...
- 解决虚拟机安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题
环境说明:系统:Windows 8.1 简体中文专业版 虚拟机:VMware Workstation 11.0.0 报错:此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态.如 ...
- Highcharts 树状图(Treemap)
Highcharts 树状图(Treemap) 树状图 series 配置 设置 series 的 type 属性为 treemap ,series.type 描述了数据列类型.默认值为 " ...
- 移动端点击(click)事件延迟问题的产生与解决方法
http://blog.csdn.net/xjun0812/article/details/64919063 问题的发现 上班做项目的时候碰到一个移动端项目,其中有个小游戏,相当于天上掉馅饼,用户需要 ...
- 004PHP基础知识——数据类型(一)
<?php /* * 数据类型(一) * 标量类型:整型(int) 浮点型(float) 字符串型(string) 布尔型(boolean) * 复合类型:数组(array) 对象(object ...
- Oracle11g创建表空间及用户
第1步:创建临时表空间 create temporary tablespace pgenius_temptempfile '/data/oracle/oradata/orcl/pgenius_te ...
- 一条命令修改Linux密码
方法一.直接使用passwd命令 /bin/echo newpass|/usr/bin/passwd --stdin username *注:该方式只适用于红帽系操作系统,比如centos,redha ...