LOJ 2270 [SDOI 2017] 天才黑客
给出一张 \(n\) 个点,\(m\) 条边的图以及一个大小为 \(k\) 的字典树,每条边有 \(x, y\) 的权值,一条路径的权值就是上面所有边的 \(x\) 之和 + 相邻两条边在字典树上的 LCA 的深度之和。
求 \(1\) 到每个点的最短路。
对于 \(100\%\) 的数据,\(T \leq 10\),\(2 \leq n \leq 50000\),\(1 \leq m \leq 50000\),\(1 \leq k \leq 20000\),保证满足 \(n > 5000\) 或 \(m > 5000\) 的数据不超过 \(2\) 组。
虚树
图论
优化连边
直接根据 xzz 讲的做法写的,没有看题解实现,然后一顿搞,于是搞了半天,最后发现有一个在 namespace
的变量然后在全局变量里面还开了一个,终于过了样例。。
感觉还是挺妙的!调出来了还是比较开心的!
先将边换成点,转换成边与边的距离,对于一个点 \(x\),我们将其所有入边和出边所代表的点连边。
比较棘手的就是这个 LCA 的深度之和,然后可以类似于 [CTSC2018] 暴力写挂 将所有点放到 Trie 树上,然后枚举作为 LCA 的这个点,然后连边。
又因为有关键点限制,于是我们可以将所有关键点建立一颗虚树,然后有如下解法:
- 对于 Trie 树上每个点,新建两个点,入点和出点。
- 每个点的出点向父亲的出点连边权为 \(0\) 的边,父亲的入点向该点的入点连一条边权为 \(0\) 的边,表示在 Trie 树上向下向上走的情况。
- 每个点的入点向出点连边权为 \(dep\) 的边,代表枚举的 LCA 的 \(dep\)
- 对于一个入边,直接将这个点连一条到 Trie 树上的节点的边,对于出边,直接连出去即可。
然后我们会发现有一个问题:
一个点可以走到根,然后原路返回,于是 \(dep = 0\) 可以随便走了
于是我们还要钦定不能原路返回,防止贡献有问题。
于是可以将第 \(3\) 点改成:
对于 \(x\) 的每个儿子 \(y\),其入点向其他儿子的出点连边权为 \(dep\) 的边权
然后要注意对于关键点的连边要考虑连边之后向上 / 向下走的情况。
本博客作者:Werner_Yin(https://www.cnblogs.com/werner-yin/) ,转载时请注明出处,谢谢支持!