询问树上距离为k的点对是否存在

直接n^2暴力处理点对 桶排记录 可以过

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int MAXN = 1e5 + ;
  6. const int MAXM = 1e5 + ;
  7. int to[MAXM << ], nxt[MAXM << ], Head[MAXN], ed = ;
  8. int cost[MAXM << ];
  9. int ok[];
  10. inline void addedge(int u, int v, int c) {
  11. to[++ed] = v;
  12. cost[ed] = c;
  13. nxt[ed] = Head[u];
  14. Head[u] = ed;
  15. }
  16. inline void ADD(int u, int v, int c) {
  17. addedge(u, v, c);
  18. addedge(v, u, c);
  19. }
  20. int n, m, k;
  21. int sz[MAXN], f[MAXN], dep[MAXN], sumsz, root;
  22. bool vis[MAXN];
  23. int o[MAXN], cnt;
  24. void getroot(int x, int fa) {
  25. sz[x] = ;
  26. f[x] = ;
  27. for (int i = Head[x]; i; i = nxt[i]) {
  28. int v = to[i];
  29. if (v == fa || vis[v]) {
  30. continue;
  31. }
  32. getroot(v, x);
  33. sz[x] += sz[v];
  34. f[x] = max(f[x], sz[v]);
  35. }
  36. f[x] = max(f[x], sumsz - sz[x]);
  37. if (f[x] < f[root]) {
  38. root = x;
  39. }
  40. }
  41. void getdeep(int x, int fa) {
  42. o[++cnt] = dep[x];
  43. for (int i = Head[x]; i; i = nxt[i]) {
  44. int v = to[i];
  45. if (v == fa || vis[v]) {
  46. continue;
  47. }
  48. dep[v] = dep[x] + cost[i];
  49. getdeep(v, x);
  50. }
  51. }
  52. void calc(int x, int d, int add) {
  53. cnt = ;
  54. dep[x] = d;
  55. getdeep(x, );
  56. sort(o + , o + cnt + );
  57. for (int i = ; i <= cnt; i++) {
  58. for (int j = i + ; j <= cnt; j++) {
  59. ok[o[i] + o[j]] += add;
  60. }
  61. }
  62. }
  63. void solve(int x) {
  64. calc(x, , );
  65. vis[x] = ;
  66. for (int i = Head[x]; i; i = nxt[i]) {
  67. int v = to[i];
  68. if (vis[v]) {
  69. continue;
  70. }
  71. calc(v, cost[i], -);
  72. root = , sumsz = sz[v];
  73. getroot(v, );
  74. solve(root);
  75. }
  76. }
  77. int main() {
  78. scanf("%d %d", &n, &m);
  79. cnt = ;
  80. memset(Head, , sizeof(Head));
  81. memset(vis, , sizeof(vis));
  82. memset(ok, , sizeof(ok));
  83. ed = ;
  84. int u, v, c;
  85. for (int i = ; i < n; i++) {
  86. scanf("%d %d %d", &u, &v, &c);
  87. ADD(u, v, c);
  88. }
  89. root = , sumsz = f[] = n;
  90. getroot(, );
  91. solve(root);
  92. for (int i = ; i <= m; i++) {
  93. scanf("%d", &k);
  94. if (ok[k]) {
  95. printf("AYE\n");
  96. } else {
  97. printf("NAY\n");
  98. }
  99. }
  100. return ;
  101. }

用类似poj1741的方法:对于每一次询问 calc()函数中求出<=k的和>=k的数量再减去总对数 则为=k的数量

复杂度为O(m*n*log2n)

  1. #include<bits/stdc++.h>
  2. #define MAXN 10005
  3. #define INF 1e9+7
  4. using namespace std;
  5. struct front_star{
  6. int to,next,w;
  7. }edge[MAXN<<];
  8. int n,cnt=,k,mx,root,ans=,tot=,siz,m;
  9. int head[MAXN],sz[MAXN],temp[MAXN],idx[MAXN];
  10. bool vis[MAXN];
  11. int maxn(int a,int b)
  12. {
  13. return a>b?a:b;
  14. }
  15. void addedge(int u,int v,int c)
  16. {
  17. cnt++;
  18. edge[cnt].to=v;
  19. edge[cnt].w=c;
  20. edge[cnt].next=head[u];
  21. head[u]=cnt;
  22. }
  23. void findroot(int u,int fa)
  24. {
  25. sz[u]=;
  26. int msz=;
  27. for(int i=head[u];~i;i=edge[i].next)
  28. {
  29. int v=edge[i].to;
  30. if(v!=fa&&!vis[v])
  31. {
  32. findroot(v,u);
  33. sz[u]+=sz[v];
  34. msz=maxn(msz,sz[v]);
  35. }
  36. }
  37. msz=maxn(msz,siz-sz[u]);
  38. if(msz<mx)
  39. {
  40. mx=msz;
  41. root=u;
  42. }
  43. }
  44. void init()
  45. {
  46. memset(head,-,sizeof(head));
  47. scanf("%d%d",&n,&m);
  48. for(int i=;i<=n-;i++)
  49. {
  50. int a,b,c;
  51. scanf("%d%d%d",&a,&b,&c);
  52. addedge(a,b,c);
  53. addedge(b,a,c);
  54. }
  55. }
  56. void dist(int u,int fa)
  57. {
  58. for(int i=head[u];~i;i=edge[i].next)
  59. {
  60. int v=edge[i].to;
  61. if(!vis[v]&&v!=fa)
  62. {
  63. tot++;
  64. idx[v]=tot;
  65. temp[tot]=temp[idx[u]]+edge[i].w;
  66. dist(v,u);
  67. }
  68. }
  69. }
  70. int count_ans(int u,int val)
  71. {
  72. tot=;
  73. idx[u]=;
  74. temp[]=val;
  75. dist(u,u);
  76. sort(temp+,temp++tot);
  77. int L=,R=tot,res1=,res2=,ret;
  78. while(L<=R)
  79. {
  80. if(temp[L]+temp[R]<=k)
  81. {
  82. res1+=R-L;
  83. L++;
  84. }
  85. else
  86. R--;
  87. }
  88. L=,R=tot;
  89. while(L<=R)
  90. {
  91. if(temp[L]+temp[R]>=k)
  92. {
  93. res2+=R-L;
  94. R--;
  95. }
  96. else
  97. L++;
  98. }
  99. ret=res1+res2-(tot*(tot-))/;
  100. return ret;
  101. }
  102. void divide(int u)
  103. {
  104. ans+=count_ans(u,);
  105. vis[u]=true;
  106. for(int i=head[u];~i;i=edge[i].next)
  107. {
  108. int v=edge[i].to;
  109. if(!vis[v]&&!vis[v])
  110. {
  111. ans-=count_ans(v,edge[i].w);
  112. siz=sz[v];
  113. mx=INF;
  114. findroot(v,u);
  115. divide(root);
  116. }
  117. }
  118. }
  119. void query()
  120. {
  121. for(int i=;i<=m;i++)
  122. {
  123. memset(vis,false,sizeof(vis));
  124. scanf("%d",&k);
  125. siz=n;
  126. mx=INF;
  127. ans=;
  128. findroot(,);
  129. divide(root);
  130. if(ans==)
  131. printf("NAY\n");
  132. else
  133. printf("AYE\n");
  134. }
  135. }
  136. int main()
  137. {
  138. init();
  139. query();
  140. return ;
  141. }

P3806 离线多次询问 树上距离为K的点对是否存在 点分治的更多相关文章

  1. 洛谷 P3806 【模板】点分治1-树分治(点分治,容斥版) 模板题-树上距离为k的点对是否存在

    P3806 [模板]点分治1 题目背景 感谢hzwer的点分治互测. 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入格式 n,m 接下来n-1条边a,b,c描述a到b有一条长度 ...

  2. POJ1741--Tree (树的点分治) 求树上距离小于等于k的点对数

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12276   Accepted: 3886 Description ...

  3. Codeforces 161.D. Distance in Tree-树分治(点分治,不容斥版)-树上距离为K的点对数量-蜜汁TLE (VK Cup 2012 Round 1)

    D. Distance in Tree time limit per test 3 seconds memory limit per test 512 megabytes input standard ...

  4. HDU 2874 Connections between cities(LCA(离线、在线)求树上距离+森林)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874 题目大意:给出n个点,m条边,q个询问,每次询问(u,v)的最短距离,若(u,v)不连通即不在同 ...

  5. POJ 1741 单次询问树上距离<=K的点对数 点分治

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; ; ], ...

  6. [HNOI2003]消防局的设立(树上距离为k的最小覆盖问题)

    题目的大概意思现在有一棵树,在树上找半径小于等于2的最小覆盖点的最小个数. 题目链接 讲一讲此类题的贪心策略: 就是每次寻找最低没有被覆盖的点,显然对于覆盖它的所有点中,在他的祖先处设立一个点最优.所 ...

  7. poj1741 树上距离小于等于k的对数 点分治 入门题

    #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...

  8. [Swift]LeetCode863. 二叉树中所有距离为 K 的结点 | All Nodes Distance K in Binary Tree

    We are given a binary tree (with root node root), a targetnode, and an integer value K. Return a lis ...

  9. Leetcode 863. 二叉树中所有距离为 K 的结点

    863. 二叉树中所有距离为 K 的结点  显示英文描述 我的提交返回竞赛   用户通过次数39 用户尝试次数59 通过次数39 提交次数174 题目难度Medium 给定一个二叉树(具有根结点 ro ...

随机推荐

  1. java中单例模式的优缺点

    一.什么叫单例 对单例类实例化后拿到的都是堆里面的同一个实例对象,通俗一点就是所有的这个单例的实例化引用都指向堆内存中的一个实例对象(有且仅有一个) 使用场景:对象需要频繁的实例化和销毁,此时考虑使用 ...

  2. js 返回一个数组里面0出现的次数

    var num = new Array(10000).fill('').map((item,index) => (index + 1)). 在点号后面补充代码,让num是这个数组中0出现的次数, ...

  3. spark-scala-java实现wordcount

    引入:spark-scala-java实现wordcount 1.spark-scala实现wordcount package com.cw.scala.spark import org.apache ...

  4. SQL SERVER 数据有CHAR(10),CHAR(13),CHAR(9)隐藏字符

    原文:SQL SERVER 数据有CHAR(10),CHAR(13),CHAR(9)隐藏字符 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Givi ...

  5. @Autowired注解与@Qualifier注解搭配使用----解决多实现选择注入问题

    问题:当一个接口实现由两个实现类时,只使用@Autowired注解,会报错,如下图所示 实现类1 实现类2 controller中注入 然后启动服务报错,如下所示: Exception encount ...

  6. IntelliJ IDEA 2017.3.2 热加载(Hot Swap)

    一.IntelliJ IDEA 自带热加载,修改代码后点击Ctrl + F9即可 缺点:1.Ctrl + F9只对当前类重新编译加载 2.只支持构造代码块的CRUD.方法体内代码修改.资源文件内容的修 ...

  7. Struts框架的使用初步

    Struts框架的使用初步: A:Apache下载struts.2.1.8.rar包. B:解压空工程,进入apps目录. C:将struts2的基本jar包拷到工程的lib目录中. D:配置web. ...

  8. HTML——form表单中常用标签 form input (text hidden password radio checkbox reset submit ) select(option)总结

    <form action="" method="get"> <!-- placeholder="请输入文本" 显示提示 r ...

  9. 异常-JDK7针对多个异常的处理方案

    package cn.itcast_02; /* * JDK7出现了一个新的异常处理方案: * try{ * * }catch(异常名1 | 异常名2 | ... 变量 ) { * ... * } * ...

  10. O050、Create Volume 操作 (Part I)

    参考https://www.cnblogs.com/CloudMan6/p/5603312.html   前面已经学习了Cinder的架构和相关组件,从本节开始详细分析 Cinder 的各种操作,首先 ...