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. 所以很多时候,当我们写出一个程序的时候,我们并不知道这个程序在并发情况下会不会出现什么问题. 所以在本 ...
随机推荐
- js创建表格
js创建一个表格,其中的表头已经有了,要从json中读取的数据一行一行地创建表格 function create_table(data){ tableNode = document.getElemen ...
- [javascript]jQuery绑定事件方法:on()
语法: $(selector).on(event,childSelector,data,function) on(event,childSelector,data,function):在被选元素及子元 ...
- 【Error】 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
mysql 登录输入密码有时会碰到如题的错误. 错误描述: Error 1045 (28000): Access denied for user 'root'@'localhost' (using p ...
- jersey实现跨服务器上传
1.导入跨服务器上传文件jar文件 <dependency> <groupId>commons-io</groupId> <artifactId>com ...
- uva 12356 Army Buddies 树状数组解法 树状数组求加和恰为k的最小项号 难度:1
Nlogonia is fighting a ruthless war against the neighboring country of Cubiconia. The Chief General ...
- 重温MVC基础入门
重温MVC基础入门 简介 本文主要是作者回顾MVC基础的文章,整合个人认为基础且重点的信息,通过简单实践进行复习. 相关代码地址:https://github.com/OtherRuan/Revi ...
- hystrix -hystrix常用配置介绍
配置官网介绍地址:https://github.com/Netflix/Hystrix/wiki/Configuration hystrix.command.default.execution.iso ...
- LeetCode OJ:Jump Game II(跳跃游戏2)
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- vue 插件(Sublime Text 3 常用插件以及安装方法)(转)
使用Package Control组件安装 也可以安装package control组件,然后直接在线安装:按Ctrl+` 调出console粘贴以下代码到底部命令行并回车: { import url ...
- HashMap resize方法的理解(一)
对于oldTable中存储的为15.7.4.5.8.1,长度为8的一个数组中,存储位置如下 0 1 2 3 4 5 6 7 8 1 4 5 15 7 当扩容到一倍后,对于新的位置的选择通过e.hash ...