前言
这个题会有两种 \(80 \textrm{pts}\) 的做法, 我会一同分析, \(100\) 先暂时放一放
一种方法, 这个先不讲, 这个方法可以做到 \(\mathcal{O} (n^2m + n^3)\), 但是这个不好玩
思路
首先考虑平均环长和需要什么: 环长 \(\&\) 环的边数
如果你在学习矩阵的时候了解过, 你会发现以下内容
关于两点间只经过 n 条边的最短路径长度
用邻接矩阵 M 表示一个图, M(i,j) 是其第 i 行第 j 列元素, 表示点 i 和点 j 的直接关系,
- 若点 i 和点 j 直接相连, 令 M[i,j] 等于边 {i,j} 的权值, 否则等于 ∞;
- 当 i=j 时, 令 M[i,i]=∞
定义矩阵的广义乘法 M×M=mink=1N[M(i,k)+M(k,j)], 也就是把普通的矩阵乘法从求和改成了取最小值, 把内部项相乘改成了相加。
注意
当 ⊕ 运算满足交换律, ⊗ 运算满足交换律、结合律,且 ⊕ 对 ⊗ 存在分配律时, 矩阵乘法具有结合律
当前
- ⊕ 运算 min 满足交换律;
- ⊗ 运算 + 满足交换律、结合律;
- ⊕ 对 ⊗ 存在分配律时 (min{α1,α1,⋯,αk}+β=min{α1+β,α2+β,⋯,αk+β} ), 这个矩阵乘法具有结合律
定理 6.3.2 计算邻接矩阵的广义幂 G=Mn, G(i,j) 的值是从 i 到 j 经过 n 条边(或 n−1 个点)的最短路径长度。
证明
当 n=1 时, G=M1=M, G 就是邻接矩阵 M, 直接的点之间有一条边, 表示只有经过一条边的路径, 路径的值是两点间的边长;非直接的点的 G 值为 ∞, 表示没有只经过一条边的路径。例如, 图 6.2(b) 中, 点 1 和点 2 的 M(1,2)=3, 表示点 1 和点 2 之间只包含一条边的路径, 最短路径是 3;M(1,3)=∞, 表示点 1 和点 3 之间只包含一条边的路径有 0 条。
当 n=2 时, G=M2=mina=1N[M(i,a)+M(a,j)], 只有当 M(i,a)=∞ 和 M(a,j)=∞ 时, 才有 M(i,a)+M(a,j)=∞, 即如果 i 到 a、a 到 j 都有边时, 值为边权之和, 这是一条从 i 到 j 经过 a 的路径, 且只经过了 a 一个点。G(i,j) 的值等于所有这种路径的最小值, 即所有从 i 到 j 经过一个中间点(或两条边)的最小路径。例如, 图 6.2(c) 中, M(2,2)=2, 表示从点 2 出发回到点 2, 经过两条边的最短路径是 2, 计算过程:M2(2,2)=min(M(2,1)+M(1,2),M(2,2)+M(2,2),M(2,3)+M(3,2),M(2,4)+M(4,2))=min(3+3,∞,1+1,5+5)=2, 3 条路径分别是 2→1→2, 2→3→2, 2→4→2, 最短路径是 2→3→2。

有了这个方法, 我们可以简单地计算出答案
但是关键问题在于这个题的边是一个指数类型的问题, 如何对上面的方法进行改造
不难发现边长可以用一个大进制数表示, 但是怎么去转移是一个问题
发现每个位置维护字符串类型的问题, 然后同样去做就行了
稍微理一下方便实现
首先跟普通的方法一样, 我们考虑定义一个矩阵 \(\mathbf{M}\), 初始为邻接矩阵
然后我们需要求的答案就是
\[ans = \max_{l = 1}^{n} \dfrac{\mathbf{M}^l (i, i)}{l}
\]
考虑其复杂度 \(\mathcal{O} (n^5)\), 显然是不优秀的
考虑为什么这个做法这么差, 但是题解做法遥遥领先, 好像这个做法不太能优化了
发现可能的原因是这个图比较稀疏?
发现什么原因都不是, 这个做法本质上就是 \(\mathcal{O} (n^5)\) 的, 但是比较 \(\min\) 的时候卡不满, 于是做到了接近 \(\mathcal{O} (n^4)\) 的复杂度, 就可以过了
最后问题是怎么去做最终的比较, 给出一份代码供参考
代码
int len = 0, len1 = 0;
for (int i = 0; i < n; i++) {
len += Val[i], len1 += rhs.Val[i];
}
double pre = 0;
for (int i = n - 1; i >= 0; i--) {
pre *= 998244353;
pre += (double)Val[i] / len;
pre -= (double)rhs.Val[i] / len1;
if (pre >= 1e9) return false;
if (pre <= -1e9) return true;
}
return pre < 0;
当然也可以通分, 反正这样那样的
\(\textrm{Thanks for }\)\(\textrm{the author}\)\(\textrm{ of the idea.}\)