【BZOJ2599】[IOI2011]Race 树的点分治
【BZOJ2599】[IOI2011]Race
Description
给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000
Input
第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)
Output
一个整数 表示最小边数量 如果不存在这样的路径 输出-1
Sample Input
0 1 1
1 2 2
1 3 4
Sample Output
题解:本题大部分代码都与POJ1741那道模板题相同,只不过是calc函数里有些不一样
如果我们想计算一棵子树里的答案,仍然是先按照每个点到根的距离排序,然后用双指针法算出长度=m的路径,那么问题来了,我们怎样将答案中的非简单路径去掉呢?
由于我们最终要求的是经过边最少的长度=m的简单路径,那么我们可以用ans[i]保存经过i条边的路径数,然后在calc的时候直接修改ans就行了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=200010;
int to[maxn<<1],next[maxn<<1],val[maxn<<1],dep[maxn],s[maxn],head[maxn],siz[maxn];
int vis[maxn],ans[maxn],p[maxn];
int n,m,tot,cnt,root,maxx; bool cmp(int a,int b)
{
return s[a]<s[b];
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void getroot(int x,int fa)
{
int i,mx=0;
siz[x]=1;
for(i=head[x];i!=-1;i=next[i])
{
if(to[i]==fa||vis[to[i]]) continue;
getroot(to[i],x);
siz[x]+=siz[to[i]];
mx=max(mx,siz[to[i]]);
}
mx=max(mx,tot-siz[x]);
if(maxx>mx) root=x,maxx=mx;
}
void getdep(int x,int fa)
{
p[++p[0]]=x;
for(int i=head[x];i!=-1;i=next[i])
{
if(to[i]==fa||vis[to[i]]) continue;
s[to[i]]=s[x]+val[i],dep[to[i]]=dep[x]+1;
getdep(to[i],x);
}
}
void calc(int x,int flag)
{
p[0]=0,getdep(x,0);
sort(p+1,p+p[0]+1,cmp);
int l=1,r=p[0],i;
for(;l<r;l++)
{
while(l<r&&s[p[l]]+s[p[r]]>m) r--;
for(i=r;i>l&&s[p[l]]+s[p[i]]==m;i--) ans[dep[p[l]]+dep[p[i]]]+=flag;
}
}
void dfs(int x)
{
vis[x]=1;
s[x]=dep[x]=0,calc(x,1);
for(int i=head[x];i!=-1;i=next[i])
{
if(vis[to[i]]) continue;
s[to[i]]=val[i],dep[to[i]]=1,calc(to[i],-1);
maxx=1<<30,tot=siz[to[i]],getroot(to[i],x);
dfs(root);
}
}
int main()
{
scanf("%d%d",&n,&m);
int i,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c),a++,b++;
add(a,b,c),add(b,a,c);
}
maxx=1<<30;
getroot(1,0);
dfs(1);
for(i=1;i<=n;i++)
{
if(ans[i])
{
printf("%d\n",i);
return 0;
}
}
printf("-1");
return 0;
}
【BZOJ2599】[IOI2011]Race 树的点分治的更多相关文章
- [bzoj2599][IOI2011]Race——点分治
Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...
- [luogu4149][bzoj2599][IOI2011]Race【点分治】
题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...
- 2019.01.09 bzoj2599: [IOI2011]Race(点分治)
传送门 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 思路: 考虑点分治如何合并. 我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可. 代码: ...
- BZOJ2599 [IOI2011]Race 【点分治】
题目 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 输入格式 第一行 两个整数 n, k 第二..n行 每行三个整 ...
- bzoj2599: [IOI2011]Race(点分治)
写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...
- BZOJ2599:[IOI2011]Race(点分治)
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- 【点分治】【哈希表】bzoj2599 [IOI2011]Race
给nlog2n随便过的跪了,不得已弄了个哈希表伪装成nlogn(当然随便卡,好孩子不要学)…… 不过为啥哈希表的大小开小点就RE啊……?必须得超过数据范围一大截才行……谜 #include<cs ...
- bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race
两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...
- BZOJ2599——[IOI2011]Race
0.题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 1.分析:水题一道,一波树分治就好 我们可以发现这个题的K是比较小的,才100w,那么我们可以树分治一下,在遍历每一棵子树的 ...
随机推荐
- linux取随机数shell版本
#!/bin/bash aa=$(-) ..} do useradd $i echo $aa|passwd --stdin $i echo "${i} ${aa}" >> ...
- Python time & datetime & string 相互转换
#!/usr/bin/env python# -*- coding:utf-8 -*- # @Datetime : 2017/11/23 下午12:37# @Author : Alfred Xue# ...
- arduino~snprintf
#include <stdio.h> printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf ...
- 第三百一十三节,Django框架,Session
第三百一十三节,Django框架,Session Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 1.数据库(默认)2.缓存3.文件4.缓存+数据库5.加密c ...
- 第二百八十五节,MySQL数据库-MySQL函数
MySQL数据库-MySQL函数 1.MySQL内置函数 SELECT执行函数,后面跟要执行的函数 CHAR_LENGTH(str)函数:返回字符串的字符长度 -- CHAR_LENGTH(str)函 ...
- Java中的内存处理机制和final、static、final static总结
Java中的内存处理机制和final.static.final static总结 装载自:http://blog.csdn.net/wqthaha/article/details/20923579 ...
- perl File::Spec 模块
File::Spec 模块提供了很多的功能,这里只列举几个常用的函数 rel2abs : 返回一个文件的绝对路径, 常见用法,返回当前运行的perl脚本的绝对路径 代码示例: my $prog = F ...
- 统计 fastq 文件 q20 , GC 含量的软件
二代测序的分析过程中,经常需要统计原始下机数据的数据量,看数据量是否符合要求:另外还需要统计q20,q30,GC含量等反应测序质量的指标: 在kseq.h 的基础上稍加改造,就可以实现从fastq 文 ...
- 使用定时器判断确保某个标签有值才执行方法, 控制js代码执行先后顺序
使用定时器判断确保某个标签有值才执行方法: var wait = setInterval(function(){ var diqu = $("#diqu").val(); //确保 ...
- jquery获取当前select下拉选的属性值
body中: <li> <select id="select_phone"></select> <input type="but ...