这个应该还不是正解,明天看一下正解到底是什么...

Code:

#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 500000
#define inf 0x7f7f7f
using namespace std;
char *q1,*q2,buf[1000000];
#define nc() (q1==q2&&(q2=(q1=buf)+fread(buf,1,1000000,stdin),q1==q2)?EOF:*q1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
int hd[maxn],to[maxn],nex[maxn],val[maxn],f[maxn],vis[maxn],siz[maxn],dep[maxn],ans,cur=0;
int cnt,n,k,root,sn,d[2];
void addedge(int u,int v,int c)
{
nex[++cnt] = hd[u],hd[u] = cnt,to[cnt] = v,val[cnt] = c;
}
struct Point{
int dis,tot;
Point(int dis = 0,int tot = 0):dis(dis),tot(tot){}
bool operator<(Point b)const{
return b.dis != dis ? b.dis>dis : b.tot > tot;
}
}point[2][maxn],pp[maxn];
void getdis(int u,int fa,int tot)
{
if(!u) return;
point[cur][++d[cur]]=Point(dep[u],tot);
for(int i = hd[u]; i ; i = nex[i])
{
if(vis[to[i]] || to[i] == fa) continue;
dep[to[i]] = dep[u] + val[i],getdis(to[i],u,tot + 1);
}
}
void GetRoot(int u,int ff)
{
siz[u] = 1,f[u] = 0;
for(int i = hd[u]; i ; i = nex[i])
{
if(vis[to[i]] || to[i] == ff) continue;
GetRoot(to[i],u);
siz[u] += siz[to[i]];
f[u] = max(f[u], siz[to[i]]);
}
f[u] = max(f[u], sn - siz[u]);
if(f[u] < f[root]) root = u;
}
void DFS(int u)
{
//calc
d[cur^1]=d[cur]=0,vis[u]=1;
point[cur^1][++d[cur^1]]=Point(0,0);
for(int i = hd[u],j,m,p1,p2; i ; i = nex[i])
{ if(vis[to[i]]) continue;
dep[to[i]]=val[i];
getdis(to[i],u,1);
sort(point[cur]+1,point[cur]+1+d[cur]);
m = 1;
for(j = 2;j <= d[cur]; ++j)
if(point[cur][j].dis!=point[cur][j-1].dis) point[cur][++m]=point[cur][j];
d[cur] = m,p1 = 1,p2 = d[cur^1];
while(p1 <= d[cur] && p2 >=1)
{
if(point[cur][p1].dis + point[cur^1][p2].dis == k)
ans = min(ans,point[cur][p1].tot + point[cur^1][p2].tot), ++p1,--p2;
if(point[cur][p1].dis + point[cur^1][p2].dis < k) ++p1;
if(point[cur][p1].dis + point[cur^1][p2].dis > k) --p2;
}
for(j = 1;j <= d[cur]; ++j) point[cur^1][++d[cur^1]] = point[cur][j];
sort(point[cur^1]+1,point[cur^1]+1+d[cur^1]);
m = 1;
for(j=2;j<=d[cur^1];++j)
if(point[cur^1][j].dis!=point[cur^1][j-1].dis)point[cur^1][++m]=point[cur^1][j];
d[cur^1]=m, d[cur]=0;
}
for(int i = hd[u]; i ; i = nex[i])
{
if(vis[to[i]]) continue;
root = 0,sn = siz[to[i]],GetRoot(to[i],u), DFS(root);
}
}
int main()
{ // setIO("input");
n=rd(),k=rd();
for(int i = 1,a,b,c;i < n; ++i) a=rd(),b=rd(),c=rd(),addedge(a+1,b+1,c),addedge(b+1,a+1,c);
ans = inf, vis[0] = 1,f[0] = inf,sn = n,root = 0, GetRoot(1,0);
DFS(root);
printf("%d\n",ans==inf?-1:ans);
return 0;
}

  

[IOI2011]Race $O(nlog^{2}n)$ 做法的更多相关文章

  1. [IOI2011]Race

    2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBhttp://www.lydsy.com/JudgeOnline/problem ...

  2. 2599: [IOI2011]Race

    2599: [IOI2011]Race 链接 分析 被memset卡... 点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少.然后先遍历子树,更新答 ...

  3. BZOJ2599 [IOI2011]Race

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

  4. BZOJ2599——[IOI2011]Race

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

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

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

  6. [Luogu4149][IOI2011]Race

    BZOJ权限题qwq Luogu sol 树上路径当然是淀粉质辣! 考虑所有过重心的路径.开一个\(10^6\)大小的数组\(t\)表示某一路径长度的最小边数,初始化为\(inf(i>0)\), ...

  7. Luogu4149:[IOI2011]Race

    题目 bzoj权限题... Luogu Sol 点分治辣,边权非负,k>=1,开个\(1e6\)的桶就好辣 # include <bits/stdc++.h> # define RG ...

  8. P4149 [IOI2011]Race

    对于这道题,明显是点分治,权值等于k,可以用桶统计树上路径(但注意要清空); 对于每颗子树,先与之前的子树拼k,再更新桶,维护t["len"]最小边数; #include < ...

  9. bzoj千题计划160:bzoj2599: [IOI2011]Race

    http://www.lydsy.com/JudgeOnline/problem.php?id=2599 点分治 mi[i] 记录边权和为i时的最少边数 先更新答案,再更新mi数组,换根时清空mi # ...

随机推荐

  1. 移位运算>>与>>>

    无符号右移运算符 (>>>)右移表达式的位,不保留符号.result = expression1 >>> expression2>>>运算符把 e ...

  2. 0804关于mysql 索引自动优化机制: 索引选择性(Cardinality:索引基数)

    转自http://blog.csdn.net/zheng0518/article/details/50561761 1.两个同样结构的语句一个没有用到索引的问题: 查1到20号的就不用索引,查1到5号 ...

  3. BA-WG-调试经验

    Modbus网关 目前常用的产品为BAM360,仅可以用做modbus RTU主站,可以从从站扫描数据,接入的数据必须为标准的MODBUS RTU从站 串口数据 使用sc-431硬件将串口数据转换为m ...

  4. HDU 3537

    翻硬币游戏,纯.. 注意要判重 #include <iostream> #include <cstdio> #include <cstring> #include ...

  5. RubyMine快捷键

    RubyMine快捷键 ctrl+shift+up/down 向上/向下移动代码段 alt+shift+up/down 向上/向下移动代码行 ctrl+y 删除一行 ctrl+shift+f10 运行 ...

  6. 怎样预置Android 手机 APK

    预制APK有下面4种情况: 1, 怎样将带源代码的 APK 预置进系统? 2, 怎样将无源代码的APK预置进系统? 3, 怎样预置APK使得用户能够卸载,恢复出厂设置时不能恢复? 4, 怎样预置APK ...

  7. 在Maven中设置Nexus私有服务为中央工厂

    在Maven中设置Nexus私有服务为中央工厂(repository) 2015-12-12 17:45 168人阅读 评论(0) 收藏 举报  分类: Maven(17)  版权声明:本文为博主原创 ...

  8. 初探swift语言的学习笔记三(闭包-匿名函数)

    作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/29353019 转载请注明出处 假设认为文章对你有所帮助,请通过留言 ...

  9. 零基础学python-2.24 一些经常使用函数

    今天我举一些经常使用的函数,让大家了解一下: 函数 作用 dir([obj]) 浏览对象的属性 help([obj]) 显示对象的文档字符串 ini([obj]) 将对象转为整形 len([obj]) ...

  10. Gym-101915B Ali and Wi-Fi 计算几何 求两圆交点

    题面 题意:给你n个圆,每个圆有一个权值,你可以选择一个点,可以获得覆盖这个点的圆中,权值最大的m个的权值,问最多权值是多少 题解:好像是叙利亚的题....我们画画图就知道,我们要找的就是圆与圆交的那 ...