其他分享
首页 > 其他分享> > FJWC2019 FZOJ191 子图 (三元环计数、四元环计数)

FJWC2019 FZOJ191 子图 (三元环计数、四元环计数)

作者:互联网

给定 n 个点和 m 条边的一张图和一个值 k ,求图中边数为 k 的联通子图个数 mod 1e9+7。

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

观察到 k 的值贼小,考虑分类讨论

下面代码中du[]代表点的度数。(度 找不到比较好的英文,而这个拼音比较巨,所以du是我的代码习惯中里出现拼音的少数几中情况之一)

观察图片

k = 1,输出 m。 k = 2, 枚举点 2,组合数一下即可。

对于 k = 3 我们分为三种情况(按照图片顺序从左到右)

图(1) 我们枚举边 2--3 ,则答案为(du[2] - 1) * (du[3] - 1)。

图(2) 我们枚举点 2 ,组合数一下即可。

图(3) 则转化为三元环计数问题。

需要注意 图(1) 中 可能出现 1 和 4 重合的情况,恰好是一个三元环。每个三元环会被统计三次。所以需要减去 3 * 三元环数量。

所以最后我们需要减去 2 * 三元环数量。

对于 k = 4,我们分为五种情况(按照图片顺序从左到右)

先考虑图(3)是一个菊花比较简单,枚举点 2 直接组合数一下即可。

然后我们考虑图(2), 我们考虑枚举 边 2--3 ,则答案为 (du[2] - 2) * (du[3] - 1) + (du[2] - 1) * (du[3] - 2)。

注意到可能存在 1 号点 和 (4号点 或 5号点) 重合的情况,那么就变成了 图(4) 。每一种图 (4) 都会被统计两次,需要减去两次 图(4) 的方案总数。

然后我们考虑图(1)。 我们考虑枚举点 3, 再依次枚举它的出边。我们开个变量 tmp 维护 已经扫过的出边的另一端点的出边数量和,即 sum(du[i] - 1) (i 是扫过的出边连接的点) 每次我们将本次扫的 (du[i] - 1) 与 tmp 乘一下累加到答案然后把 (du[i] - 1) 加到 tmp 里。

这里 我们会有三种重合情况:(假设点 2 是之前枚举过的点, 点 4 是当前正在枚举的点)

  1. 点 5 和 点 1 重合。 那么图变成了四元环,即图(5)。每个四元环会在这里被统计四次,接下来需要 -= 4 * 四元环方案数。
  2. 点 5 和 点 2 重合,点 1 和点 4 不重合。 那么图变成了图(4)。每个 图(4) 会在这里被统计两次, 接下来需要 -= 2 * 四元环方案数。
  3. 点 5 和 点 2 重合,点 1 和点 4 重合。 那么图变成了一个三元环。每个三元环会在这里被统计三次,接下来需要 -= 3 * 三元环方案数。

然后考虑图(4)。图 4 是有一个三元环和一条边组成。我们考虑枚举点 2 , ans += 点 2 所在三元环数量 * (du[2] - 2) 。

考虑图(5)。图(5)是一个四元环计数。

现在我们把问题转化成了给定图求每个点所在三元环数量,以及四元环总数。三元环数量可以用给每个点三元环数量 / 3 来求出。

首先考虑求每个点所在三元环的数量。

这是常数比较大的 \(O(m \sqrt m)\) 的算法,另外还有 \(O(m \sqrt n)\) 的转化为有向图的常数较小的做法,没看太懂这里不解释

我们考虑把点分为两种,第一种是度数 \(du[x] \le \sqrt m\) 的,第二种是度数 \(du[x] > \sqrt m\) 的 (一下简称第一种点、第二种点)。

然后我们三元环分为两类,第一类是包含第一种点的三元环, 第二类是不包含第一种点的三元环(环上所有点都是第二种点)。

先考虑枚举所有第一种点 x, 我们考虑枚举所有无序出边对,然后我们就可以得到三个顶点 (x, y, z) 。我们可以维护一个 set ,然后直接判断这三个点是否构成三元环。 如果构成三元环我们考虑统计答案。 首先 对于所有第一类点,我们会枚举所有三元环,直接在枚举这个点时暴力统计贡献即可。 对于第二类点,假设 y 和 z 都是第二类点, 那么 (x, y, z) 这个三元环只会在此时被统计,我们将 ans[y]++, ans[z]++。 如果 y 和 z 中只有一个第二类点(假设y),那么三元环 (x, y, z) 会被枚举两次,其中 x 和 z 是第一类点。而 y 只能被统计一次,我们可以考虑当 x 的标号 小于 z 的标号时候将 ans[y]++ 以避免重复统计。这一部分的时间复杂度为 \(O(m \sqrt m)\),因为每条边最多只会作为第一条出边出现两次,而每个点 x 的出度是 \(O(\sqrt m)\) 级别的,所以第二条出边最多为 \(O(\sqrt m)\) 个,所以复杂度为 \(O(m \sqrt m)\) 。

然后我们考虑枚举第二类三元环。由于第二类点的个数 \(\le \sqrt m\) 个

标签:FJWC2019,子图,sqrt,计数,枚举,出边,三元,du,考虑
来源: https://www.cnblogs.com/oier/p/10538811.html