图论基础
参考资料
引言
主要是以基础知识为主,一些板子,还有一些容易错的写法。
注意事项
-
判断一个点是割点要求是存在 \(low[v]\ge dfn[u]\) 即可,还有是根节点且独立的子树至少两个。判断\((u,v)\) 是割边要求是 \(low[v]>dfn[u]\)。
-
点双联通需要计入 \(u\),但不需要将其弹出栈,注意要判断孤点。边双连通不需要计入 \(u\)。注意最后要把栈中剩余的点拿出来组成新的边双。
-
点双有两种定义。一种定义是“图中任意两不同点之间都有至少两条点不重复的路径”,而另外一种是“不存在割点的图”,一般是后者。
-
一个点只属于一个边双,但可能属于多个点双。
-
在双联通分量中都是加入新的分量考虑 \(u\) 的儿子 \(v\),而强联通分量加入新的分量是考虑 \(u\),条件是 \(low[u]=dfn[u]\)。
-
欧拉路径模板中一定要注意 \(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 $ 已经能访问所有点了那么就没有必要添加算法源点。
一些性质
-
差分约束系统有可行解,当且仅当约束图不存在负环。
-
最紧上界:若 \(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})\)。
启发:
- 正解记住小的连向小的即可。
- bitset怎么这么牛。

浙公网安备 33010602011771号