BZOJ2599——[IOI2011]Race
0、题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小.
1、分析:水题一道,一波树分治就好
我们可以发现这个题的K是比较小的,才100w,那么我们可以树分治一下,在遍历每一棵子树的时候我们知道要统计两个不同子树之间的权值,如果我们全遍历然后再getans,我们就会发现某个子树自己会和自己进行统计了一下,这样不太好,所有我们每遍历一个子树我们就把这个子树中从x所有长度为k的路径记录上v[k]=边数,记住要取min,然后询问我们还是遍历子树,我们查询v[K - k]然后统计答案。。这样我们就能轻松的查询了,最后别忘记把所有v数组清空,记住不要memset,会TLE,我们还是再次的遍历一下。。
然后我们就AC了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define M 2000010
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
struct Edge{
int u,v,w,next;
} G[M];
int head[M],tot;
int mx[M],size[M],ok[M],mi,root;
int n,k,V[M],ans;
int vis[M];
inline void add(int u,int v,int w){
G[++tot]=(Edge){u,v,w,head[u]};
head[u]=tot;
}
inline void dfssize(int x,int fa){
size[x]=1;mx[x]=0;
for(int i=head[x];i!=-1;i=G[i].next) if(G[i].v!=fa&&!ok[G[i].v]){
dfssize(G[i].v,x);
size[x]+=size[G[i].v];
if(size[G[i].v]>mx[x]) mx[x]=size[G[i].v];
}
}
inline void getroot(int r,int x,int fa){
if(size[r]-size[x]>mx[x]) mx[x]=size[r]-size[x];
if(mx[x]<mi) mi=mx[x],root=x;
for(int i=head[x];i!=-1;i=G[i].next) if(G[i].v!=fa&&!ok[G[i].v]){
getroot(r,G[i].v,x);
}
}
inline void dfs_getans(int x,int fa,int edge,int val){
if(val>k)return;
if(val==k){
ans=min(ans,edge);
return;
}
int o=k-val;
if(V[o]!=0){
ans=min(ans,edge+V[o]);
}
for(int i=head[x];i!=-1;i=G[i].next) if(G[i].v!=fa&&!ok[G[i].v]){
dfs_getans(G[i].v,x,edge+1,val+G[i].w);
}
}
inline void dfs_insert(int x,int fa,int edge,int val){
if(val>=k)return;
if(!V[val]) V[val]=edge;
else V[val]=min(V[val],edge);
for(int i=head[x];i!=-1;i=G[i].next) if(G[i].v!=fa&&!ok[G[i].v]){
dfs_insert(G[i].v,x,edge+1,val+G[i].w);
}
}
inline void dfs_delete(int x,int fa,int edge,int val){
if(val>=k)return;
V[val]=0;
for(int i=head[x];i!=-1;i=G[i].next) if(G[i].v!=fa&&!ok[G[i].v]){
dfs_delete(G[i].v,x,edge+1,val+G[i].w);
}
}
inline void solve(int x){
mi=n; dfssize(x,0);
getroot(x,x,0);
ok[root]=1;
for(int i=head[root];i!=-1;i=G[i].next) if(!ok[G[i].v]){
dfs_getans(G[i].v,root,1,G[i].w);
dfs_insert(G[i].v,root,1,G[i].w);
}
for(int i=head[root];i!=-1;i=G[i].next) if(!ok[G[i].v]){
dfs_delete(G[i].v,root,1,G[i].w);
}
for(int i=head[root];i!=-1;i=G[i].next) if(!ok[G[i].v]){
solve(G[i].v);
}
}
int main(){
n=read(),k=read();
memset(head,-1,sizeof(head));
for(int i=1;i<n;i++){
int u=read(),v=read(),w=read();
u++; v++;
add(u,v,w); add(v,u,w);
}
ans=214748364;
solve(1);
if(ans==214748364) puts("-1");
else printf("%d\n",ans);
return 0;
}
BZOJ2599——[IOI2011]Race的更多相关文章
- [bzoj2599][IOI2011]Race——点分治
Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...
- bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race
两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...
- bzoj2599: [IOI2011]Race(点分治)
写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...
- BZOJ2599 [IOI2011]Race
传送门 点分治,黄学长的选根方法会T掉,换了这个人的选根方法就可以了. 当然,你也可以选择黄学长的奇淫优化 //BZOJ 2599 //by Cydiater //2016.9.23 #include ...
- [luogu4149][bzoj2599][IOI2011]Race【点分治】
题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...
- 2019.01.09 bzoj2599: [IOI2011]Race(点分治)
传送门 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 思路: 考虑点分治如何合并. 我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可. 代码: ...
- bzoj千题计划160:bzoj2599: [IOI2011]Race
http://www.lydsy.com/JudgeOnline/problem.php?id=2599 点分治 mi[i] 记录边权和为i时的最少边数 先更新答案,再更新mi数组,换根时清空mi # ...
- BZOJ2599:[IOI2011]Race(点分治)
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- 【点分治】【哈希表】bzoj2599 [IOI2011]Race
给nlog2n随便过的跪了,不得已弄了个哈希表伪装成nlogn(当然随便卡,好孩子不要学)…… 不过为啥哈希表的大小开小点就RE啊……?必须得超过数据范围一大截才行……谜 #include<cs ...
随机推荐
- java编程思想-java中的并发(三)
三.终结任务 1. 在阻塞时终结 线程状态 一个线程可以处于以下四种状态之一: 1)新建(new):当线程被创建时,他只会短暂的处于这种状态.此时,他已经分配了必须的系统资源,并执行了初始化.此刻线程 ...
- xfce4 dev tools的一些说明
xfce4 dev tools实际上基本是封装了一些autoconf的宏函数 比如XDT_I18N: AC_DEFUN([XDT_I18N], [ dnl Substitute GETTEXT_PAC ...
- nginx访问日志获取访问前10的url
在ELK里面获取top10的url在日志量非常大的情况下是非常消耗内存的,所以写了一个脚本用来快速获取. 配置文件 log.conf [log] log_file = /data/logs/nginx ...
- host,nslookup,dig 命令安装
host,nslookup,dig依赖bind包,所以先看一下系统有没有bind包 命令如下:rpm -qa |grep bind 如果没有或者版本太低请升级安装 命令是:yum install bi ...
- 10月14日上午PHP环境搭建
第一步:安装wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-64b文件,安装过程中可能会遇到问题,把遇到的问题代码复制粘贴到360人工服务,查找方案 ...
- C#操作XML,如何获取指定节点值?
博客园提问,结合网友回答http://q.cnblogs.com/q/36082/ 打开是treelist树形显示xml所有节点,递归来实现 xmlDoc = new XmlDocument(); ...
- Quagga服务器安装和配置
使用本地源 一.安装软件包 # yum install quagga-0.99.15-7.el6_3.2.x86_64.rpm 或rpm # ls /etc/quagga/ bgpd.conf.s ...
- JavaScript中变量和函数声明的提升
现象: 1.在JavaScript中变量和函数的声明会提升到最顶部执行. 2.函数的提升高于变量的提升. 3.函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4.匿名函数不会提升. ...
- Centos7安装rabbitmq server 3.6.0
###假设所有操作在opt目录下进行 cd /opt mkdir apps cd apps ### 下载 RabbitMQ Server wget http://www.rabbitmq.com/re ...
- redis缓存分页数据ID
1.用户通过分类.属性进来分页时 如果没有缓存,就读数据库前10页的数据Id,转为json,根据cate_分类1+cate_分类2+cate_分类3+arr_属性1+arr_属性2+arr_属性3作为 ...