2599: [IOI2011]Race

Time Limit: 70 Sec  Memory Limit: 128 MB
Submit: 2476  Solved: 733
[Submit][Status][Discuss]

Description

给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小.

Input

第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3
0 1 1
1 2 2
1 3 4

Sample Output

2

HINT

 

Source

 题解:
  随便点分治,用一个ans[i]代表u,v距离为k,边数为i的点对个数,那么答案就为i (ans[i]>0 && i 最小);
  怎么求ans? 自己yy一下吧
代码:
  

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define N 200100
using namespace std;
int tot,n,m,all,k,root,sum;
int pre[N*],v[N*],val[N*],now[N],size[N],ans[N],f[N];
bool vis[N];
struct data{int val,size;
}d[N],da[N];
bool cmp(data a,data b)
{
return a.val<b.val;
}
int read()
{
int x=; char ch; bool bo=;
while (ch=getchar(),ch<''||ch>'') if (ch=='-') bo=;
while (x=x*+ch-'',ch=getchar(),ch>=''&&ch<='');
if (!bo) return -x; return x;
}
void ins(int a,int b,int c)
{
++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; val[tot]=c;
}
void getroot(int u,int fa)
{
size[u]=; f[u]=;
for (int p=now[u]; p; p=pre[p])
{
int son=v[p];
if (vis[son]||son==fa) continue;
getroot(son,u);
size[u]+=size[son];
f[u]=max(f[u],size[son]);
}
f[u]=max(f[u],all-size[u]);
if (f[u]<f[root]) root=u;
}
void getarray(int u,int fa)
{
for (int p=now[u]; p; p=pre[p])
{
int son=v[p];
if (son==fa||vis[son]) continue;
da[++sum].val=d[son].val=d[u].val+val[p];
da[sum].size=d[son].size=d[u].size+;
getarray(son,u);
} }
void calc(int u,int value, int f)
{
d[u].val=value; if (f==) d[u].size=; else d[u].size=;
sum=; da[++sum].val=value; da[sum].size=d[u].size;
getarray(u,);
sort(da+,da++sum,cmp);
for (int i=,j=sum; i<=j; i++)
{
while (j>i && da[j].val+da[i].val>k) j--;
for (int p=j; da[i].val+da[p].val==k ;p--)ans[da[p].size+da[i].size]+=f;
}
}
void solve(int u)
{
vis[u]=; calc(u,,);
for (int p=now[u]; p; p=pre[p])
{
int son=v[p];
if (vis[son]) continue;
calc(son,val[p],-);
all=size[son];
root=; getroot(son,);
solve(root);
}
}
int main()
{
n=read(); k=read();
for (int i=; i<n; i++)
{
int u=read()+,v=read()+,value=read();
ins(u,v,value); ins(v,u,value);
}
all=n; f[root=]=n; getroot(,);
solve(root);
for (int i=; i<n; i++)
{
if (ans[i])
{
printf("%d\n",i);
return ;
}
}
printf("-1\n"); return ;
}

bzoj2599的更多相关文章

  1. bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race

    两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...

  2. 【BZOJ2599】Race(点分治)

    [BZOJ2599]Race(点分治) 题面 BZOJ权限题,洛谷 题解 好久没写过点分治了... 在ppl的帮助下终于想起来了 orz ppl 首先回忆一下怎么求有没有正好是\(K\)的路径 维护一 ...

  3. 【BZOJ2599】[IOI2011]Race 树的点分治

    [BZOJ2599][IOI2011]Race Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 100000 ...

  4. [bzoj2599][IOI2011]Race——点分治

    Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...

  5. [bzoj2599][IOI2011]Race_树上点分治

    Race bzoj-2599 题目大意:询问一颗树上最短的.长度为k的链,边有边权,n个节点. 注释:$1\le n \le 2\cdot 10^5$,$1\le k \le 10^6$. 想法:树上 ...

  6. bzoj2599: [IOI2011]Race(点分治)

    写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...

  7. 【BZOJ-2599】Race 点分治

    2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 2590  Solved: 769[Submit][Status ...

  8. BZOJ2599 [IOI2011]Race

    传送门 点分治,黄学长的选根方法会T掉,换了这个人的选根方法就可以了. 当然,你也可以选择黄学长的奇淫优化 //BZOJ 2599 //by Cydiater //2016.9.23 #include ...

  9. BZOJ2599——[IOI2011]Race

    0.题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 1.分析:水题一道,一波树分治就好 我们可以发现这个题的K是比较小的,才100w,那么我们可以树分治一下,在遍历每一棵子树的 ...

  10. [BZOJ2599][Race][IOI2011]点分治

    这是为了真正去学一下点分治..然后看了迪克李的ppt 又是一道写(改)了很久的题..终于ac了 1354799 orzliyicheng 2599 Accepted 31936 kb 23584 ms ...

随机推荐

  1. 仿照微信的界面,即ViewPager+Fragment的结合使用

    主布局文件: android:drawableTop="@drawable/weixin_bg"用的是状态选择器,所以要写4个状态选择器,图片的 <RelativeLayou ...

  2. 【转】PHP代码审计

    PHP代码审计 目录 1. 概述3 2. 输入验证和输出显示3 2.1 命令注入4 2.2 跨站脚本4 2.3 文件包含5 2.4 代码注入5 2.5 SQL注入6 2.6 XPath注入6 2.7 ...

  3. jquery获取页面相关尺寸

    $(windows).width();获取页面可视宽度 $(windows).height();获取页面可视高度 $(document).height();获取页面内容的总高度 $(document) ...

  4. 母亲的牛奶(milk)

    母亲的牛奶(milk) 题目描述 农民约翰有三个容量分别是A.B.C升的桶,A.B.C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的.有时,约翰把牛奶从一个桶倒到另一个桶中,直 ...

  5. android脚步---UI界面修改,关于activity中增加按钮和监听

    增加按钮和监听,这个和上个不同在于,它不是在一个dialog里面,而是从新写了一个activity,因此需要先找到这个activity的入口. case R.id.checkframe: if (mC ...

  6. android脚步---简单图片浏览器改变图像透明度

    图片浏览器调用ImageView的setAlpha方法来实现改变图片透明度. main.xml文件如下:三个按钮,两个imageview,,界面定义了两个ImageView,一个是显示局部图片的Ima ...

  7. FZU Problem 2213 Common Tangents

    其实是不太好意思往博客上放的,因为是一道巨水的题,但是我却错了一次,没有判断重合,放上还是为了警示自己,尽量不要在水题上罚时 #include<iostream> #include< ...

  8. brbustoj 1818 石子合并问题--直线版

    比较经典且基础的区间dp,转移方程为 dp_max[i][j] = max(dp_max[i][j],dp_max[i][k] + dp_max[k+1][j] + sum[j]-sum[i-1]); ...

  9. hihoCoder 1257 Snake Carpet(很简单的构造方法)

    2015 ACM / ICPC 北京现场赛 I 题 构造 注意一个小坑,每条蛇的输出是要从头到尾输出的. 还要注意的是,不能开数组去模拟构造过程,然后输出,那样会TLE的. #include < ...

  10. Python3基础 函数 收集参数+普通参数 的示例

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...