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();
    }
}

你可能感兴趣的:(BZOJ 1002 [轮状病毒])