有标号串广义并联图计数
前言
下文中所有图若无强调则均指无向简单(无重边自环)图。
如题,接下来我们将在 \(O(n^5)\) 的时间内计算 \(n\) 个点 \(m\) 条边的广义串并联图个数对质数取模的结果。
正文
定义与引理
记号
对于一张图 \(G\),定义其的顶点集合为 \(V_G\),边集合为 \(E_G\)。
图收缩操作
定义三种图收缩操作:
-
rake假若 \(u\) 是一个度数为 \(1\) 的顶点,那么将其与和其相连的边一同删去。 -
compress假若 \(u\) 是一个度数为 \(2\) 的顶点,假设其邻域为 \(\{v,w\}\),那么将边 \((v,u),(w,u)\) 和点 \(u\) 一并删去,并加入边 \((v,w)\)。 -
twice将两条边 \((u,v)\) 合并为一条。
广义串并联图
如果一个联通图可以通过不断进行图收缩操作变成一个孤立点则称此图为广义串并联图。
引理 1
一个广义串并联图 \(G\) 可以通过若干次图收缩操作变成一条 \(E_G\) 中存在的边。
对图 \(G\) 建出 Top tree \(T\),接下来我们归纳地证明:对于 \(u \in T\),定义 \(sub_u\) 表示 \(u\) 子树内的点构成的子图,定义 \(path_u\) 表示 \(u\) 的上下界点构成的边,我们可以通过若干次图收缩操作将 \(G \backslash sub_u\) 内的点和边变成 \(\emptyset\) 或者 \(path_u\)。
假若 \(u\) 是 Top tree 的根,该结论显然成立。
否则如果:
-
\(u\) 的父亲是
rake节点,假若 \(path_u=path_{{fa_u}}\),则可以将 \(u\) 的兄弟节点收缩为 \(\emptyset\) 即可,否则将 \(path_{fa_u}\) 和 \(u\) 的兄弟一并收缩为 \(\emptyset\) 即可。 -
\(u\) 的父亲是
compress节点,将 \(u\) 的兄弟 \(v\) 收缩成 \(path_v\) 之后,如果 \(path_{fa_u}\) 存在则对 \(path_{fa_u}\) 和 \(path_v\) 执行一次compress操作,否则对 \(path_v\) 执行rake。 -
\(u\) 的父亲是
twice节点,将 \(u\) 的兄弟 \(v\) 收缩成 \(path_v\) 之后,如果 \(path_{fa_u}\) 存在则对 \(path_{fa_u}\) 和 \(path_v\) 执行一次twice操作。
从上到下归纳即可证明该引理。
引理 2
如果一个联通图 \(G\) 可以通过进行若干次图收缩操作可以变成边 \((u,v)\) 当且仅当该图加上边 \((u,v)\) 后仍然是广义串并联图。
充分性证明:
由引理 1 可得图 \(G\) 加上边 \((u,v)\) 后可以通过进行若干次图收缩变成边 \((u,v)\),而在该收缩过程中,由于最后保留了边 \((u,v)\) 以及点 \(u,v\),所以过程中所有操作均不涉及对点 \(u,v\) 的度数要求,又因为图 \(G\) 本身是联通的,所以一定对新加入的边 \((u,v)\) 执行过 twice 操作。因此图 \(G\) 本身也可以通过执行若干次图收缩操作变成边 \((u,v)\)。
必要性证明:
在图 \(G\) 执行若干次图收缩操作变成边 \((u,v)\) 的收缩过程中:由于最后保留了边 \((u,v)\) 以及点 \(u,v\),所以过程中所有操作均不涉及对点 \(u,v\) 的度数要求,所以我们往图 \(G\) 上加入一条额外的边 \((u,v)\) 不会影响收缩过程,最后将额外加入的边与原本的边先执行一次 twice 操作再执行一次 rake 操作即可将图变成孤立点。因此加上边 \((u,v)\) 后的新图也是广义串并联图。
具体做法
对于联通图 \(G\) 不断进行图收缩操作后会剩下的图要么是一个孤立点要么是一张唯一确定的图 \(G'\),所以我们考虑先数出 \(n\) 点 \(m\) 边的联通图数目,再减去收缩后会得到某张图 \(G'\) 的图数即可。
考虑枚举 \(G'\) 的形态再去计算多少张图收缩后会得到 \(G'\)。首先不难发现 \(G'\) 应当满足:
-
是联通简单图。
-
所有点度数均大于等于 \(3\)。
我们称这样的图为 \(3-core\) 图。
考虑由 \(G'\) 还原为 \(G\) 的过程:我们将 \(G'\) 中每条边都还原为可以收缩为这条边的一张图,不同边之间不会相互干扰(也就是说 \(G'\) 上任意两条不同边的收缩过程是独立的),同时可以在 \(G'\) 中每个点上挂一些收缩之后可以作为 \(1\) 度点被直接删去的图。
设 \(f_{i,j}\) 表示多少张 \(i+2\) 个点 \(j\) 条边的图(点标号 \(s,t,1,2,\dots,i\))能收缩为边 \((s,t)\),\(g_{i,j}\) 表示多少张 \(i+1\) 个点 \(j\) 条边的图(点标号 \(x,1,2,\dots,i\))能收缩为点 \(x\)。\(dp_{i,j}\) 表示 \(i\) 个点 \(j\) 条边的广义串并联图个数,\(z_{i,j}\) 表示 \(i\) 个点 \(j\) 条边的 \(3-sore\) 图个数。
首先 \(DP(x,y)=\sum_{i=0} \sum_{j=0} z_{i,j}\frac{x^i}{i!}y^jF(x,y)^iG(x,y)^j\) 是不对的。原因是可能有一部分被 rake 到 \(u\) 上的点被 \(F\)(即 compress 到边 \((u,v)\) 上)和 \(G\)(即 rake 到 \(u\) 上)同时统计到。
所以我们定义 \(f'_{i,j}\) 表示多少张 \(i+2\) 个点 \(j\) 条边的图(点标号 \(s,t,1,2,\dots,i\))能在不执行涉及 \(s\) 或者 \(t\) 的 rake 操作的前提下收缩为边 \((s,t)\)。那么就有 \(DP(x,y)=\sum_{i=0} \sum_{j=0} z_{i,j}\frac{x^i}{i!}y^jF'(x,y)^iG(x,y)^j\)。
计算 \(3-core\) 图数量
设 \(z_{i,j}\) 表示 \(i\) 个点 \(j\) 条边的 \(3-core\) 图数量,为了计算 \(z\) 我们考虑如下算法:
-
先计算出 \(i\) 个点 \(j\) 条边的简单图数目。
-
对于一张简单图,我们钦定其中的孤立链,孤立环,挂在点上的链,挂在点上的环,点之间的链的结构并容斥。具体地:我们用 dp 过程逐步加入被钦定的结构,并在 dp 过程中记录除开所有被钦定的结构后剩下的点数,加入被钦定的结构后的点数与边数,暴力转移即可做到 \(O(n^4)\)。需要注意用每次加入结构内最小点编号最小的结构防止算重。
计算 \(G(x,y)\)
不难发现 \(G(x,y)=DP(x+1,y)\)。
计算 \(F'(x,y)\)
我们先利用引理 2 计算出 \(F(x,y)\)。讨论加入的边 \((s,t)\) 是否是重边,如果不是再讨论一下是不是割边。
计算 \(DP(x,y)\)
直接暴力卷积是 \(O(n^6)\) 的,分步卷积即可做到 \(O(n^5)\)。
其他
好像拉插优化一下卷积之类的就做到 \(O(n^4)\) 了。

浙公网安备 33010602011771号