这是为了真正去学一下点分治。。然后看了迪克李的ppt

又是一道写(改)了很久的题。。终于ac了

1354799 orzliyicheng 2599 Accepted 31936 kb 23584 ms C++/Edit 2218 B 2016-03-27 15:55:17

不算快呢。。具体实现是看的hzwer的blog,然而迪克李的ppt已经将想法讲得很清楚了

uoj文件里有,就懒得贴题解了

刚刚写完的时候,一个极限数据要跑60sec,我也是醉了。。主要原因有:

1.清空数组的时候竟然跑了n遍for循环,这不是显然O(n^2),我是不是傻。。(改完以后跑了30sec

2.getdeep,亦或是Add,都必须是对一整颗子树,我好像直接当前节点就开始了啊。。(这样下来时间就差不多了

然而还是有bug

都是一些没清零之类的问题。。晕@_@

然后就很开心地贴了,成功wa     要来数据发现第十个点就错了

改了有毛两个小时。。那是一条链的情况。。还以为有哪条路径没考虑到呢。。

原来只是边权为零的问题。。。。。。。。。

QAQ于是一个下午就这么过去了。。下次再写点分治应该效率会变高了吧

听说黄学长的getroot有一些问题会很慢。。?然而我并不觉得呀,还是留到以后再看吧。。(懒)

/**************************************************************
    Problem: 2599
    User: orzliyicheng
    Language: C++
    Result: Accepted
    Time:23584 ms
    Memory:31936 kb
****************************************************************/

#include<cstdio>
#include<algorithm>
#define N 400100
using namespace std;
int edgenum,k,n,root,m,w,ans,sum,u,v,rn;
],head[N],pri[N],dis[],fa[N];
void getroot(int u,int fa)
{
  son[u]=;ff[u]=;int e=head[u];
  )
  {
    int v=vet[e];
    &&v!=fa)
    {
      getroot(v,u);son[u]+=son[v];
      ff[u]=max(ff[u],son[v]);
    }
    e=next[e];
  }
  ff[u]=max(ff[u],sum-son[u]);
  if(ff[u]<ff[root])root=u;
}
void Add(int u,int fa,int biao)
{
  if(dis[u]<=k)
  {
    )f[dis[u]]=min(f[dis[u]],s[u]);;
  }
  int e=head[u];
  )
  {
    int v=vet[e];
    )if(v!=fa)
    {
      Add(v,u,biao);
    }
    e=next[e];
  }
}
void getdeep(int u,int fa)
{
  if(k>=dis[u])if(f[k-dis[u]]+s[u]<ans)ans=f[k-dis[u]]+s[u];
  int e=head[u];
  )
  {
    int v=vet[e];
    &&v!=fa)
    {
      s[v]=s[u]+;dis[v]=dis[u]+pri[e];
      getdeep(v,u);
    }
    e=next[e];
  }
}
void work(int u)
{
  dis[u]=;s[u]=;flag[u]=;
  int e=head[u];rn=u;
  )
  {
    int v=vet[e];
    )
    {
      dis[v]=dis[u]+pri[e];s[v]=s[u]+;
      getdeep(v,),Add(v,,);
    }
    e=next[e];
  }
  e=head[u];
  )
  {
    int v=vet[e];
    )Add(v,,);
    e=next[e];
  }f[]=;
  e=head[u];
  )
  {
    int v=vet[e];
    )
    {
      root=;sum=son[v];
      getroot(v,);work(root);
    }
    e=next[e];
  }
}
void add(int u,int v,int w)
{
  edgenum++;vet[edgenum]=v;next[edgenum]=head[u];head[u]=edgenum;
  pri[edgenum]=w;
}
int main()
{

  scanf("%d%d",&n,&k);
  ;i<=n-;i++)
  {
    scanf("%d%d%d",&u,&v,&w);u++;v++;
    add(u,v,w);add(v,u,w);
  }
  ff[]=sum=n;ans=n*;
  ;i<=k;i++)f[i]=n*;
  f[]=;
  root=;getroot(,);work(root);
  ;
  printf("%d",ans);
  //fclose(stdin);fclose(stdout);
}

算是吧省选一试以后的一个遗留问题给解决了。。

大家去安徽集训了,也不知道可以系统地做什么。。那就先颓一会儿文化课吧,先把月考给考了。嗯

[BZOJ2599][Race][IOI2011]点分治的更多相关文章

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

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

  2. 【BZOJ2599】Race(点分治)

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

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

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

  4. [luogu4149][bzoj2599][IOI2011]Race【点分治】

    题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...

  5. bzoj2599/luogu4149 [IOI2011]Race (点分治)

    点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...

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

    传送门 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 思路: 考虑点分治如何合并. 我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可. 代码: ...

  7. BZOJ2599 [IOI2011]Race 【点分治】

    题目 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 输入格式 第一行 两个整数 n, k 第二..n行 每行三个整 ...

  8. bzoj 2599 [IOI2011]Race (点分治)

    [题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...

  9. 【Luogu P4149】[IOI2011]Race(点分治)

    自闭了几天后的我终于开始做题了..然后调了3h一道点分治板子题,调了一天一道IOI... 最后还是自己手造数据debug出来的... 这题一看:树上路径问题,已知路径长度求balabala,显然是点分 ...

随机推荐

  1. Java异常题库

    一.填空题 __异常处理__机制是一种非常有用的辅助性程序设计方法.采用这种方法可以使得在程序设计时将程序的正常流程与错误处理分开,有利于代码的编写和维护. 在Java异常处理中可以使用多个catch ...

  2. springMVC创建基础变量

    在springMVC中有一些变量是基础变量,可以在全局多个地方使用,在修改规则的时候,这样只用修改一个地方就好了,而且可以避免很多不必要的bug出现下面就来总结一下在我的项目中如何去创建一个全局基础变 ...

  3. shell之数值运算

    Shell中声明变量默认是字符串, 要参与数值运算,可使用下面方式,简单,表示以数值方式.

  4. Android 中的缓存机制与实现

    Android开发本质上就是手机和互联网中的web服务器之间进行通信,就必然需要从服务端获取数据,而反复通过网络获取数据是比较耗时的,特别是访问比较多的时候,会极大影响了性能,Android中可通过二 ...

  5. 自动复制转换StringBuffer

    自动复制转换StringBuffer http://www.cnblogs.com/coqn/archive/2012/07/31/all_StringBuufer.html http://blog. ...

  6. mipi和dsi

    转自: http://blog.csdn.net/longxiaowu/article/details/24410021 一.MIPI MIPI(移动行业处理器接口)是Mobile Industry ...

  7. c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

    转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...

  8. 关于Mesos和Kubernetes的区别

    这个主题应该和服务发现注册一样,进入视野...

  9. OpenMesh 读写网格控制(读取写入纹理坐标,法向等)

    OpenMesh读取网格默认是不自动读取obj网格中的法向,纹理坐标等信息的,写入网格同样也是.所以要读取(或写入)这些信息需要修改默认的选项. 先看一下其读写网格的函数 template<cl ...

  10. POJ 1163:The Triangle

    Description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a progr ...