图论基础

参考资料

引言

主要是以基础知识为主,一些板子,还有一些容易错的写法。

注意事项

  1. 判断一个点是割点要求是存在 \(low[v]\ge dfn[u]\) 即可,还有是根节点且独立的子树至少两个。判断\((u,v)\) 是割边要求是 \(low[v]>dfn[u]\)。

  2. 点双联通需要计入 \(u\),但不需要将其弹出栈,注意要判断孤点。边双连通不需要计入 \(u\)。注意最后要把栈中剩余的点拿出来组成新的边双。

  3. 点双有两种定义。一种定义是“图中任意两不同点之间都有至少两条点不重复的路径”,而另外一种是“不存在割点的图”,一般是后者。

  4. 一个点只属于一个边双,但可能属于多个点双。

  5. 在双联通分量中都是加入新的分量考虑 \(u\) 的儿子 \(v\),而强联通分量加入新的分量是考虑 \(u\),条件是 \(low[u]=dfn[u]\)。

  6. 欧拉路径模板中一定要注意 \(head[u]\) 要动态维护,\(i\) 也要。

差分约束

知识点

形如 \(x_u-x_v\le w\),可以转化为等价的三角形不等式 \(x_u\le x_v+w\),因为可能有负权,可以用 SPFA 跑了,如果出现负环那么说明无解。

所有约束先统一成 \(x_v \leq x_u + w\),再连 \(u \to v_o\)

总结一些常见的形式:

原约束 标准形 边
\(x_v - x_u \leq c\) \(x_v \leq x_u + c\) \(u \to v\)(权 \(c\))
\(x_v - x_u \geq c\) \(x_v \leq x_u - c\) \(v \to u\)(权 \(-c\))
\(x_v = x_u + c\) 两个方向 \(u \to v\)(权 \(c\)),\(v \to u\)(权 \(-c\))

一些注意事项:

  • $ x_v - x_u \geq w $ 改写为 $ x_u - x_v \leq -w $;

  • $ x_v - x_u = w $ 拆成两个方向的不等式;

  • 区间和约束先用前缀和变量改写成差。

  • 以上讲的都是相对约束,如果是形如 \(x_u\le w\) 这种是绝对约束,需要建立数值源点与之相连。

源点

算法源点:

正确性依赖每条边都被松弛,因此最短路源点要能访问到所有边。一种合法的方式是增加超级源点 $ s $ 向所有点连 0 边。

数值源点:

我们为了使所有约束都是相对约束,添加变量 $ x_0 $ 作为数值源点,绝对约束就可以化成和 $ x_0 $ 的相对约束,同时最后减去 $ x_0 $ 最后的值就是一组合法赋值了。(由于常常用 $ x_0 $ 作为起点所以值大概率是 0)

一般的差分约束不认为两者等同,但是如果恰好数值源点 $ x_0 $ 已经能访问所有点了那么就没有必要添加算法源点。

一些性质

  1. 差分约束系统有可行解,当且仅当约束图不存在负环。

  2. 最紧上界:若 \(x_0=0\),从 \(0\) 出发到达 \(v\),\(dis_v\) 就是 \(x_v\) 的最大值。

三元环计数

P1989 【模板】无向图三元环计数

题目大意

给定一张无向图,求其中三元环个数。

\(1\le n\le 10^5,1\le m\le 2\times 10^5\)。

解题思路

标准解法

我们考虑将其定向成有向图,优先由度数小的连向度数大的,如果度数一样就编号小的连向编号大的。容易发现,形成的新图一定是个 DAG。

我们考虑在新图上做,枚举 \(u\) 的有向边 \((u,v)\),判断是否存在 \((v,w)\) 满足存在 \((u,w)\)。这个可以在枚举 \(u\) 的时候先给 \(u\) 能到的 \(w\) 打上标记,然后枚举 \(v\) 判断即可。由于每一条边 \((u,v)\) 对答案的贡献是 \(out_v\)。复杂度是 \(O(\sum_{i=1}^m out_{v_i})\)。能到 \(O(m\sqrt m)\)。

分析一下复杂度,显然跟出度有关。对 \(v\) 根号分治一下:

  • 原图上 \(v\) 的度数 \(\le \sqrt m\),新图上的出度不可能更大,故 \(out_v\le \sqrt m\)。
  • 原图上 \(v\) 的度数 \(> \sqrt m\),由于我们的连边规则,\(v\) 连向的点一定都是度数 \(>\sqrt m\),所以最多只能连向 \(m\over \sqrt m\),故 \(out_v\le \sqrt m\)。

所以总复杂度是 \(O(m\sqrt m)\)。

bitset

如果你想不到正解那样的定向。直接用 bitset 来优化枚举判断 \((u,v),(v,w)\) 是否有 \((u,w)\),用 & 还有 count 之后时间复杂度是 \(O({nm\over w})\)。很能过,但是空间复杂度爆炸了,\(O({n^2\over w})\),这是存不下的。

由于这是领接矩阵,所以它必然有很多位置是浪费的了,我们尝试根号分治一下,对于度数 \(>B\) 的位置存,否则暴力找,这样就对了,时间复杂度 \(O({nm\over w}+mB)\),空间复杂度 \(O({nm\over Bw})\)。

启发:

  1. 正解记住小的连向小的即可。
  2. bitset怎么这么牛。
posted @ 2026-10-18 19:20  lcx_OIer  阅读(7)  评论(0)    收藏  举报