BZOJ 1002 [轮状病毒]
题面
题意
求环上有 \(n\) 个节点的轮形图生成树的个数。
题解
环上有 \(n\) 个节点的轮形图用邻接矩阵可表示为:
\[ \underbrace{
\begin{bmatrix}
0 & 1 & 1 & 1 & \cdots & 1 & 1 \\
1 & 0 & 1 & 0 & \cdots & 0 & 1 \\
1 & 1 & 0 & 1 & \cdots & 0 & 0 \\
1 & 0 & 1 & 0 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
1 & 0 & 0 & 0 & \cdots & 0 & 1 \\
1 & 1 & 0 & 0 & \cdots & 1 & 0 \\
\end{bmatrix}
}_{n+1} \]
根据矩阵树定理,构造邻接矩阵对应的基尔霍夫矩阵:
\[ \underbrace{
\begin{bmatrix}
n & -1 & -1 & -1 & \cdots & -1 & -1 \\
-1 & 3 & -1 & 0 & \cdots & 0 & -1 \\
-1 & -1 & 3 & -1 & \cdots & 0 & 0 \\
-1 & 0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
-1 & 0 & 0 & 0 & \cdots & 3 & -1 \\
-1 & -1 & 0 & 0 & \cdots & -1 & 3 \\
\end{bmatrix}
}_{n+1} \]
同样根据矩阵树定理,基尔霍夫矩阵的任何一个代数余子式都相等,且等于生成树的数量。取划去第一行第一列的代数余子式,则生成树的数量等于:
\[ \underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & -1 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
-1 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n}\]
取出右上角和左下角的 \(-1\) 及其余子式,发现:
\[\underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & -1 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
-1 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n} =
\underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
0 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n} -
\underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
0 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n-2} -2
\]
令 \(f(n)=\underbrace{ \begin{vmatrix} 3 & -1 & 0 & \cdots & 0 & 0 \\ -1 & 3 & -1 & \cdots & 0 & 0 \\ 0 & -1 & 3 & \cdots & 0 & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & 0 & \cdots & 3 & -1 \\ 0 & 0 & 0 & \cdots & -1 & 3 \\ \end{vmatrix} }_{n}\),也就是说,答案就是 \(f(n)-f(n-2)-2\)。
对该行列式的第一行展开,化简,发现:
\[\underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
0 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n}=
3\underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
0 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n-1}
-\underbrace{
\begin{vmatrix}
3 & -1 & 0 & \cdots & 0 & 0 \\
-1 & 3 & -1 & \cdots & 0 & 0 \\
0 & -1 & 3 & \cdots & 0 & 0 \\
\vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\
0 & 0 & 0 & \cdots & 3 & -1 \\
0 & 0 & 0 & \cdots & -1 & 3 \\
\end{vmatrix}
}_{n-2}
\]
也就是 \(f(n)=3f(n-1)-f(n-2)\)。通过这个递推式,很容易就能计算出答案的值。为了方便,用了 Java 的大整数。
代码
import java.util.*;
import java.math.*;
public class Main{
public static BigInteger bigint(int n){
return new BigInteger(String.valueOf(n));
}
public static void main(String[] args){
Scanner in=new Scanner(System.in);
int i,n=in.nextInt();
BigInteger[] a=new BigInteger[n+1];
BigInteger ans;
a[1]=bigint(3);
a[2]=bigint(8);
for (i=3;i<=n;i++) {
a[i]=a[i-1].multiply(bigint(3));
a[i]=a[i].subtract(a[i-2]);
}
ans=a[n].subtract(a[n-2]);
ans=ans.subtract(bigint(2));
System.out.println(ans.toString());
in.close();
}
}

浙公网安备 33010602011771号