树上问题
qq_45778406
这个作者很懒,什么都没留下…
展开
-
MMSet2
Link思路:前置知识 lca树的的直径求法:最深的一个点一定是直径的一端直径的中点到树上最远的距离最小。#include <bits/stdc++.h>using namespace std;const int N = 3e5 + 10;int d[N], fa[N][21];int n;`int e[N<<2], ne[N<<2], h[N], cnt, p[N*10];void add(int x, int y){ e[cnt]原创 2021-12-27 19:36:36 · 232 阅读 · 0 评论 -
Full Depth Morning Show(换根法, 树形dp)
Link题目大意: 给一颗树, 树中每个点都有一个权值, 每个边都有一个边权,定义两个点的距离为d(u, v) = (u和v的路径上边权之和乘以u和v的点权之和)现求每个点到其他所有点的距离。思路:由于数据范围过大, 显然不能暴力枚举两个点之间的距离, 而且如果暴力枚举中显然有大量的数据被重复计算, 显然联想到树形dp, 用换根法进行转移。细节见于代码,一种传参, 一种记录值#include <bits/stdc++.h>using namespace std;#define in原创 2021-03-07 20:26:47 · 217 阅读 · 0 评论 -
Kill the tree(树的重心,合并子树)
Link大概题意:给一个nnn个点的树, 求每个子树的重心, 如果子树的重心不止一个, 就按照升序以空格分割。重心性质1,以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。2,树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。3,把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。4,在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。5,树的重心最多只有两个, 且两个重心相邻。思路参考题解原创 2021-03-05 16:59:38 · 299 阅读 · 0 评论 -
Destroy Walls(思维+最大生成树)
Link题意给出 n 个城市的坐标 xi,yi,有 m 个城墙,第 ui 个城市和第 vi 个城市之间是一道城墙(ui 不能直接到达vi),破坏该城墙需要 wi 的花费,问使得使整个图联通的最小花费。思路如果一个区域与另外一个区域无法联通那么其一定被城墙环绕, 我们只需要拆掉其最小的权值的那个边就好了, 也就是把所有的环变成一颗树或者多棵树就好了, 至于没用到的边就是需要拆掉的边细节见于代码#include <bits/stdc++.h>using namespace std;原创 2021-03-04 20:25:59 · 178 阅读 · 1 评论 -
Query on A Tree(可持续01线段树+dfs序)
Link题意给你一棵树,每个节点有权值,Q次询问,求u为跟的子树一个点与x亦或后的值最大是多少。思路对于异或我们很容易联想到异或, 但显然对于每个点都需要开一个01字典树, 但如果每个点都开一个01字典树来表示其子树,显然空间不够, 所以引出了可持续化01字典树,和主席树类似。所以我们先按照前序遍历建立可持续化01字典树然后对于每个查询 u, xl = st[u], r = st[u];我们用 root[l - 1]这个01字典树和root[r], 来对比出以u为根的字典树,然后直接查询最大原创 2021-03-04 00:00:00 · 584 阅读 · 1 评论 -
距离(lca,倍增, tarjan)
Link给出 n个点的一棵树,多次询问两点之间的最短距离。注意:边是无向的。所有节点的编号是 1,2,…,n。输入格式第一行为两个整数 n和 m。n 表示点数,m表示询问次数;接下来 n−1行,每行三个整数 x,y,k,表示点 x 和点 y 之间存在一条边长度为 k;再接下来 m行,每行两个整数 x,y,表示询问点 x 到点 y的最短距离。树中结点编号从 1到 n。输出格式共 m行,对于每次询问,输出一行询问结果。数据范围2≤n≤1042≤n≤1042≤n≤104,1≤m原创 2021-02-23 00:56:08 · 126 阅读 · 0 评论