题目链接【http://poj.org/problem?id=1741】

题意:

  给出一颗树,然后寻找点对(u,v)&&dis[u][v] < k的对数。

题解:

  这是一个很经典的树分治的题。假设我们选择了一个参考点u,那么对于不同的点对(u,v),(u , v)之间的路径有两种情况,经过点u,和不经过点u,加入我算出了没有经过点u的对数,然后把经过点u的加起来就是答案了,很简单,这就是分治的思想。具体看代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e4 + 15;
int N, lit;
struct Edge
{int to, next, len;Edge() {}Edge(int to, int next, int len): to(to), next(next), len(len) {}
} E[maxn * 2];
int head[maxn], tot;
void initEdge()
{for(int i = 0; i <= N + 5; i++) head[i] = -1;tot = 0;
}
void addEdge(int u, int v, int len)
{E[tot] = Edge(v, head[u], len);head[u] = tot++;E[tot] = Edge(u, head[v], len);head[v] = tot++;
}
int vis[maxn];
int dep[maxn], L, R;
int sz[maxn];
void GetSize(int u, int fa)
{sz[u] = 1;for(int k = head[u]; ~k; k = E[k].next){int v = E[k].to;if(v == fa || vis[v]) continue;GetSize(v, u);sz[u] += sz[v];}
}
void GetRoot(int u, int fa, int tot, int &rt)
{int ma = tot - sz[u];if(ma > tot / 2) return ;for(int k = head[u]; ~k; k = E[k].next){int v = E[k].to;if(v == fa || vis[v]) continue;GetRoot(v, u, tot, rt);ma = max(ma, sz[v]);}if(ma <= tot / 2) rt = u;
}
void GetPath(int u, int fa, int len)
{dep[R++] = len;for(int k = head[u]; ~k; k = E[k].next){int v = E[k].to;if(v == fa || vis[v]) continue;GetPath(v, u, len + E[k].len);}
}
int GetNum(int L, int R)
{int ret = 0;int pos = R - 1;sort(dep + L, dep + R);for(int i = L; i < R; i++){while(pos > i && dep[i] + dep[pos] > lit) pos--;if(pos > i) ret += pos - i;else break;}return ret;
}
int GetAns(int u)
{int ret = 0, rt = 0;GetSize(u, -1);GetRoot(u, -1, sz[u], rt);//找到重心vis[rt] = 1;//重心为分界点for(int k = head[rt]; ~k; k = E[k].next){int v = E[k].to;if(vis[v]) continue;ret += GetAns(v);//不过rt点的个数
    }L = R = 0;for(int k = head[rt]; ~k; k = E[k].next){int v = E[k].to;if(vis[v]) continue;GetPath(v, rt, E[k].len);ret -= GetNum(L, R);L = R;}ret += GetNum(0, R);for(int i = 0; i < R; i++)if(dep[i] <= lit) ret++;else break;vis[rt] = 0;return ret;
}
int main ()
{while(~scanf("%d %d", &N, &lit)){if(N == 0 && lit == 0) break;initEdge();for(int i = 1; i < N; i++){int u, v, len;scanf("%d %d %d", &u, &v, &len);addEdge(u, v, len);}int ans = GetAns(1);printf("%d\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/pealicx/p/7506530.html

POJ 1741 树分治相关推荐

  1. POJ 1741 Tree 树分治

    题意: 给出一颗有\(n (n \leq 10^4)\)个节点的树,和一个\(k\).统计有多少个点对\(u, \, v(u \neq v)\)满足\(u\)到\(v\)的最短距离不超过\(k\). ...

  2. POJ1741:Tree——题解+树分治简要讲解

    http://poj.org/problem?id=1741 题目大意:给一棵树,求点对间距离<=k的个数. -------------------- 以这道题为例记录一下对于树分治的理解. 树 ...

  3. Tree(树分治入门)

    题目链接:http://poj.org/problem?id=1741 Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions ...

  4. [POJ 1741] Tree

    Link: POJ 1741 传送门 Solution: 此题的难点在于点分治上的统计 如果依然采取每棵子树的结果与之前所有子树的结果合并的方式会比较麻烦 同时复杂度可能超过$O(n*log(n))$ ...

  5. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  6. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  7. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  8. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

  9. 3237: [Ahoi2013]连通图 线段树分治

    题解: cf765f cf671e bzoj4184 bzoj4552 线段树分治裸题 还是介绍一下线段树分治 这个东西其实挺简单但也挺有用的 可以把删除+插入操作变成只有插入(倒着就是删除) 像这一 ...

最新文章

  1. HDU2112(SPFA算法)
  2. java 必备_Java基础必备
  3. 解读eXtremeComponents代码结构--转载
  4. OpenCV findContours函数参数
  5. 【视频课】言有三每天答疑,38课深度学习+超60小时分类检测分割数据算法+超15个Pytorch框架使用与实践案例助你攻略CV...
  6. android 文件读取错误,Android源文件从SD卡读取错误问题,怎么处理
  7. MDC日志logback整合使用
  8. word2vec应用场景_介绍Word2Vec和Glove这两种最流行的词嵌入方法背后的直觉
  9. eclipse中启动tomcat的项目路径
  10. 取出Cookie中的中文显示乱码解决方法。经验证第三种方法有效。
  11. gtp怎么安装系统_gpt分区怎么重装系统|GPT分区重装系统win10详细步骤
  12. 吴恩达深度学习系列笔记
  13. 玩转DWZ (一)---项目中怎么使用dwz
  14. 阿里云短信服务(JAVA)
  15. make时 No rule to make target错误解决办法
  16. C语言实现时间差计算
  17. 互联网人养娃 真就和别人不一样
  18. 影评(一):《寄生虫》韩国(2019)
  19. 实战24:基于opencv神经网络Flask实现口红图片色号识别及商品推荐系统 附完整版代码
  20. SQL Server 中日期比较

热门文章

  1. flutter listview 滚动到底部_Flutter常用Widget详解(三)
  2. php隐藏webshell_【web端权限维持】利用ADS隐藏webshell
  3. unity延迟执行下一行代码_Python代码在Linux环境下执行错误异常
  4. 计算机在轻化工程中的应用,计算机在基础化学实验当中的应用
  5. 四川网络推广浅析新站要如何更快的获得好排名?
  6. java.library.path hadoop_java - Hadoop“无法为您的平台加载native-hadoop库”警告
  7. rs485调试软件_5种RS485切换方向的方法及优劣势分析
  8. python双引号和单引号区别_Python中单引号,双引号,3个单引号及3个双引号的区别...
  9. feign session 调用_springboot使用feign调用session传递失效解决方案
  10. scikit-learn系列之如何存储和导入机器学习模型