题意

4908 Race 0x49「数据结构进阶」练习

描述

给定一棵 N 个节点的树,每条边带有一个权值。

求一条简单路径,路径上各条边的权值和等于K,且路径包含的边的数量最少。

输入格式

第一行两个整数 N, K。

第2~N行每行三个整数x,y,z,表示一条无向边的两个端点x,y和权值z,点的编号从0开始。

输出格式

一个整数,表示最少边数量。如果不存在满足要求的路径,输出-1。

样例输入

  1. 4 3
  2. 0 1 1
  3. 1 2 2
  4. 1 3 4

样例输出

  1. 2

数据范围与约定

  • N <= 200000, K <= 1000000

来源

IOI2011

  1. </article>

分析

训练指南的配套代码有问题,双指针绝对是错的。学习了hzwer的做法。

开一个100W的数组t,t[i]表示权值为i的路径最少边数

找到重心分成若干子树后, 得出一棵子树的所有点到根的权值和x,到根c条边,用t[k-x]+c更新答案,全部查询完后

然后再用所有c更新t[x]

这样可以保证不出现点分治中的不合法情况

把一棵树的所有子树搞完后再遍历所有子树恢复T数组,如果用memset应该会比较慢

时间复杂度\(O(n \log^2 n)\)

代码

网上好多代码,点分治递归的时候没有重新统计以重心为根的整棵树每个节点的size,按道理找出来的重心是错的,复杂度没有保证。

但是出题人根本就不会卡这种东西,所以不用写了,反而常数小。

  1. #include<bits/stdc++.h>
  2. #define rg register
  3. #define il inline
  4. #define co const
  5. template<class T>il T read(){
  6. rg T data=0,w=1;rg char ch=getchar();
  7. while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
  8. while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
  9. return data*w;
  10. }
  11. template<class T>il T read(rg T&x) {return x=read<T>();}
  12. typedef long long ll;
  13. using namespace std;
  14. typedef pair<int,int> pii;
  15. co int N=2e5+1;
  16. int n,k,ans,sum,root,max_size;
  17. vector<pii> e[N];
  18. int t[1000001],s[N],d[N],c[N],v[N];
  19. void getroot(int x){
  20. v[x]=1,s[x]=1;
  21. int max_part=0;
  22. for(int i=0,y;i<e[x].size();++i){
  23. if(v[y=e[x][i].first]) continue;
  24. getroot(y);
  25. s[x]+=s[y],max_part=max(max_part,s[y]);
  26. }
  27. max_part=max(max_part,sum-s[x]);
  28. if(max_part<max_size) root=x,max_size=max_part;
  29. v[x]=0;
  30. }
  31. void cal(int x){
  32. v[x]=1;
  33. if(d[x]<=k) ans=min(ans,c[x]+t[k-d[x]]);
  34. for(int i=0,y;i<e[x].size();++i){
  35. if(v[y=e[x][i].first]) continue;
  36. c[y]=c[x]+1,d[y]=d[x]+e[x][i].second;
  37. cal(y);
  38. }
  39. v[x]=0;
  40. }
  41. void add(int x,int flag){
  42. v[x]=1;
  43. if(d[x]<=k){
  44. if(flag) t[d[x]]=min(t[d[x]],c[x]);
  45. else t[d[x]]=n;
  46. }
  47. for(int i=0,y;i<e[x].size();++i){
  48. if(v[y=e[x][i].first]) continue;
  49. add(y,flag);
  50. }
  51. v[x]=0;
  52. }
  53. void work(int x){
  54. v[x]=1,t[0]=0;
  55. for(int i=0,y;i<e[x].size();++i){
  56. if(v[y=e[x][i].first]) continue;
  57. c[y]=1,d[y]=e[x][i].second;
  58. cal(y),add(y,1);
  59. }
  60. for(int i=0,y;i<e[x].size();++i){
  61. if(v[y=e[x][i].first]) continue;
  62. add(y,0);
  63. }
  64. for(int i=0,y;i<e[x].size();++i){
  65. if(v[y=e[x][i].first]) continue;
  66. sum=max_size=s[y];
  67. getroot(y),work(root);
  68. }
  69. }
  70. int main(){
  71. // freopen(".in","r",stdin),freopen(".out","w",stdout);
  72. read(n),read(k);
  73. fill(t+1,t+k+1,n);
  74. for(int i=1,u,v,w;i<n;++i){
  75. read(u),read(v),read(w);
  76. e[++u].push_back(pii(++v,w)),e[v].push_back(pii(u,w));
  77. }
  78. ans=sum=max_size=n;
  79. getroot(1),work(root);
  80. if(ans==n) puts("-1");
  81. else printf("%d\n",ans);
  82. return 0;
  83. }

CH4908 Race的更多相关文章

  1. Promise.race

    [Promise.race] 返回最先完成的promise var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 5 ...

  2. golang中的race检测

    golang中的race检测 由于golang中的go是非常方便的,加上函数又非常容易隐藏go. 所以很多时候,当我们写出一个程序的时候,我们并不知道这个程序在并发情况下会不会出现什么问题. 所以在本 ...

  3. 【BZOJ-2599】Race 点分治

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

  4. hdu 4123 Bob’s Race 树的直径+rmq+尺取

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  5. Codeforces Round #131 (Div. 2) E. Relay Race dp

    题目链接: http://codeforces.com/problemset/problem/214/E Relay Race time limit per test4 secondsmemory l ...

  6. 【多线程同步案例】Race Condition引起的性能问题

    Race Condition(也叫做资源竞争),是多线程编程中比较头疼的问题.特别是Java多线程模型当中,经常会因为多个线程同时访问相同的共享数据,而造成数据的不一致性.为了解决这个问题,通常来说需 ...

  7. Codeforces Round #328 (Div. 2) C. The Big Race 数学.lcm

    C. The Big Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/592/probl ...

  8. HDU 4123 Bob’s Race 树的直径 RMQ

    Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=41 ...

  9. [LOJ 1038] Race to 1 Again

    C - Race to 1 Again Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu D ...

随机推荐

  1. struts访问

    struts基本工程结构: 1. struts.xml支持语法提示;2. struts.xml配置常量, 用来覆盖struts.properties中的默认常量配置  一般情况下, 这个配置放在str ...

  2. HotSpot虚拟机对象探秘

    参考:http://www.infoq.com/cn/articles/jvm-hotspot

  3. VSTO杂项拾零(持续更新中……)

    环境:win 7+visual basic 2008     侧重:VSTO     界面:sheetbook工作簿 1.创建一个过程并调用(2017.6.3) Public Class Sheet1 ...

  4. Remove duplicates from array II

    //Given a sorted array, remove the duplicates in place such that each element appear only // once an ...

  5. [ZJOI2008]泡泡堂BNB

    这个题...是一道神奇的贪心题... 根据田忌赛马的原理... 先假使两队都符合田忌和齐王的配置... 我们可以发现如果我们用当前最弱的...去和对方当前最强的打... 然后一直按照这个方案...当我 ...

  6. Fedora的一些个人配置

    0,老传统 yum install screenfetch 1,关闭蜂鸣器 edit /etc/bashrc setterm -blength 0#setterm -bfreq 10 #这个可以设置声 ...

  7. 杭电多校第四场 E Matrix from Arrays

    Problem E. Matrix from Arrays Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 ...

  8. day 34 进程线程排序 抢票 初级生产者消费者

    # 实现的内容 模拟购票 20个人买,就有一张购票查,的时候大家都看到,但是购买只能一人购买成功#利用互斥锁# from multiprocessing import Process,Lock# im ...

  9. 如何HACK无线家用警报器?

    30年前,报警器都是硬连线的,具有分立元件,并由钥匙开关操作.20年前,他们已经演变为使用微控制器,LCD和键盘,但仍然是硬连线.10年前,无线报警器开始变得普及,并增加了许多之前没有的功能. 而如今 ...

  10. Python 深度递归

    class A: pass class B(A): pass class C(A): pass class D(B, C): pass class E: pass class F(D, E): pas ...