bzoj 2599
还是点对之间的问题,果断上点分治
同样,把一条路径拆分成经过根节点的两条路径,对不经过根节点的路径递归处理
然后,我们逐个枚举根节点的子树,计算出子树中某一点到根节点的距离,然后在之前已经处理过的点中找,看有没有距离之和等于k的,如果有就取最小值(这里用桶维护即可)
然后再把这个子树内的信息扔进桶里,计算下一棵子树即可
但是注意,在递归处理之前需要把桶清空!
然后就没啥了
不合法的情况就是无法更新出答案,输出-1即可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int inf=0x3f3f3f3f;
struct Edge
{
int next;
int to;
int val;
}edge[];
int head[];
int cnt=;
int n,k;
int s,rt;
int siz[];
int maxp[];
bool vis[];
int dep[];
int dis[];
int has[];
int ans=0x3f3f3f3f;
void init()
{
memset(head,-,sizeof(head));
cnt=;
}
void add(int l,int r,int w)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
head[l]=cnt++;
}
void get_rt(int x,int fa)
{
siz[x]=,maxp[x]=;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
get_rt(to,x);
siz[x]+=siz[to];
maxp[x]=max(maxp[x],siz[to]);
}
maxp[x]=max(maxp[x],s-siz[x]);
if(maxp[x]<maxp[rt])rt=x;
}
void calc(int x,int fa)
{
if(dis[x]<=k)ans=min(ans,dep[x]+has[k-dis[x]]);
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
dep[to]=dep[x]+,dis[to]=dis[x]+edge[i].val;
calc(to,x);
}
}
void update(int x,int fa)
{
if(dis[x]<=k)has[dis[x]]=min(has[dis[x]],dep[x]);
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
update(to,x);
}
}
void erase(int x,int fa)
{
if(dis[x]<=k)has[dis[x]]=inf;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
erase(to,x);
}
}
void solve(int x)
{
vis[x]=,has[]=;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
dep[to]=,dis[to]=edge[i].val;
calc(to,);
update(to,);
}
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
erase(to,);
}
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
s=siz[to],rt=,maxp[rt]=inf;
get_rt(to,);
solve(rt);
}
}
int main()
{
scanf("%d%d",&n,&k);
init();
for(int i=;i<=k;i++)has[i]=n;
for(int i=;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
x++,y++;
add(x,y,z),add(y,x,z);
}
ans=maxp[rt]=s=n;
get_rt(,);
solve(rt);
ans=(ans==n)?-:ans;
printf("%d\n",ans);
return ;
}
bzoj 2599的更多相关文章
- BZOJ 2599 Race(树分治)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 题意:每次 ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- bzoj 2599: [IOI2011]Race (点分治 本地过了就是过了.jpg)
题面:(复制别人的...) Description 给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的 ...
- 【刷题】BZOJ 2599 [IOI2011]Race
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- bzoj 2599(点分治)
2599: [IOI2011]Race Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 3642 Solved: 1081[Submit][Statu ...
- 【BZOJ 2599】【IOI 2011】Race 点分治
裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...
- bzoj 2599 数分治 点剖分
具体可以见漆子超的论文 /************************************************************** Problem: User: B ...
- bzoj 2599 [IOI2011]Race (点分治)
[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...
- BZOJ 2599 [IOI2011]Race【Tree,点分治】
给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数. 点分治,这道题目和POJ 2114很接近,2114是 ...
随机推荐
- luogu3687-[ZJOI2017] 仙人掌
Description P3687 [ZJOI2017]仙人掌 - 洛谷 | 计算机科学教育新生态 Solution 我们先考虑只有一棵树如何处理. 仙人掌可以看做若干环的集合. 特别的, 对于一条没 ...
- [BJOI2019]奥术神杖(分数规划,动态规划,AC自动机)
[BJOI2019]奥术神杖(分数规划,动态规划,AC自动机) 题面 洛谷 题解 首先乘法取\(log\)变加法,开\(c\)次根变成除\(c\). 于是问题等价于最大化\(\displaystyle ...
- PAT 甲级真题题解(1-62)
准备每天刷两题PAT真题.(一句话题解) 1001 A+B Format 模拟输出,注意格式 #include <cstdio> #include <cstring> #in ...
- NOI2019十二省联考旅游记
真的是去旅游的啊,毕竟菜是原罪嘛 Day 0 去指定地点试机,果然,键盘还是一如既往的不好用,我也不知道为什么. 晚上,教练请吃自助餐,幸福的像个胖子 Day 1 早上坐车过去,在车上看了看原来写过的 ...
- MySql数据库字段排序规则不一致产生的一个问题
最近项目向MySql迁移,迁移完毕后,在获取用户权限时产生了一个异常,跟踪进去获取执行的语句如下, SELECT PermissionId FROM spysxtPermission WHERE (R ...
- ORA-00923: FROM keyword not found where expected(单双引号)
1.前提 在学习oracel的过程中遇到的一个关于单双引号的问题 备注一下 2.学习过程中创建表语句是这样的 create table DEPT_DML --部门表( DEPT_NO NUMBER(8 ...
- JS学习笔记Day17
一. 创建对象的方法 (一)在了解原型链之前,首先先了解一下创建对象的几种方式,介绍以下三种. 代码: <script type="text/javascript"> ...
- marquee标签的使用
marquee语法 <marquee></marquee> 实例一<marquee>Hello, World</marquee> marquee常 ...
- python3.x执行post请求时报错“POST data should be bytes or an iterable of bytes...”的解决方法
使用python3.5.1执行post请求时,一直报错"POST data should be bytes or an iterable of bytes. It cannot be of ...
- Attention Model(注意力模型)思想初探
1. Attention model简介 0x1:AM是什么 深度学习里的Attention model其实模拟的是人脑的注意力模型,举个例子来说,当我们观赏一幅画时,虽然我们可以看到整幅画的全貌,但 ...