图论相关做题记录

QOJ14718 Meeting for Meals

对于一个人 \(i\) 来说,他需要找到一个人 \(j\) 和他在某一条边汇合,然后共同走到 \(1\)。首先求出 \(t_{meet}\),然后最大陪伴时间就是 \(t_{meet}\) 减去最小汇合时间。

发现枚举人不好做,考虑枚举汇合的边 \((u,v,w)\)。对于 \(i\)\(j\) 两个人在这条边上汇合,需要满足 \(\min(d_{i,u}+w+d_{v,1},d_{i,v}+w+d_{u,1})\leq t_{meet}\),含义是汇合的时候从 \(v\) 离开或者从 \(u\) 离开。此时汇合时间为 \(\dfrac{d_{i,u}+w+d_{j,v}}{2}\),我们显然让 \(d_{i,u}\)\(d_{j,v}\) 尽可能小,即只需要更新距离 \(u\) 最近的一个出发点的答案和距离 \(v\) 最近的一个出发点的答案。对于距离比较远的那些点,可以被其他边 \((u',v',w')\) 更新到。具体证明可以使用反证法。

则处理出 \(f_i\) 表示距离 \(i\) 最近的出发点的位置即可,跑一遍最短路就做完了。

CF1033E Hidden Bipartite Graph

一种找到二分图的方法是,先找到一颗生成树,然后奇数深度的为左部点,偶数深度的为右部点。

先考虑如何找出一颗生成树,首先最开始以 \(1\) 为根,寻找出所有与 \(1\) 有连边的点。然后再换一个点继续与剩下的点集寻找连边。这个过程有 \(n-1\) 次。

现在有一个问题,给定一个点 \(S\) 和集合 \(T\),如何快速在集合 \(T\) 中找到点 \(u\) 与点 \(S\) 有连边。已知可以通过两次询问 \(\text{Ask}(S\cup T)-\text{Ask}(T)\) 得知点 \(S\) 与集合 \(T\) 之间的连边数量。那么我们可以通过二分在 \(2\log n\) 次询问下找到第一个存在边的点了。

综上所述,找到生成树需要 \(2n\log n\) 次询问。

现在判断是否是二分图,把奇数深度的节点放在集合 \(p\),把偶数深度节点放在集合 \(q\)。以集合 \(p\) 为例,如果集合 \(p\) 内部有点之间连边,那么就不是二分图。具体的,我们枚举集合 \(p\) 中的每一个元素 \(u\),再通过二分寻找点 \(u\) 与集合 \(p\setminus\{u\}\) 之间的边。找到边之后,把在生成树上的路径输出即可,这一定是一个奇环。

故总共需要 \(4n\log n\) 次询问,但是有很多冗余,最后大概 \(13000\) 次左右。

posted @ 2026-01-06 21:31  Otue  阅读(4)  评论(0)    收藏  举报