分析:
裸的ST(生成树)个数...
先介绍一下Matrix Tree定理:一个图的ST个数就是度数矩阵减邻接矩阵的n-1阶主子式的行列式的绝对值。
我们不难得出这道题的行列式形如:
我们假设g(i)为上面那个行列式左上的i行主子式。
运用拉普拉斯展开,不难得出上面那个行列式的值等于g(n-1)*3-g(n-2)*2-2
同理可以得出g的递推公式为g(i) = g(i-1)*3-g(i-2),初始化g(1) = 3, g(2) = 8
然后套个高精就行了(高精是以前写的,代码有些乱)
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 1005;
struct BigInt {
int a[maxn];
//构造函数
BigInt() {
memset(a, 0, sizeof a);
a[0] = 1;
}
BigInt(long long n) {
*this = n;
}
//赋值
BigInt operator = (long long n) {
a[0] = 1;
if(n == 0)
a[1] = 0;
else {
while(n != 0) {
a[a[0]++] = n % 10;
n /= 10;
}
a[0]--;
}
return *this;
}
//基本运算符
BigInt operator + (const BigInt &b) const {
BigInt c;
int temp = 0;
while(c.a[0] <= a[0] || c.a[0] <= b.a[0]) {
c.a[c.a[0]] = a[c.a[0]] + b.a[c.a[0]] + temp;
temp = c.a[c.a[0]] / 10;
c.a[c.a[0]++] %= 10;
}
c.a[c.a[0]] = temp;
for(int i = c.a[0]; i > 1; i--)
if(!c.a[i])
c.a[0]--;
else break;
return c;
}
BigInt operator - (const BigInt &b) const {
BigInt c;
int temp = 0;
while(c.a[0] <= a[0] || c.a[0] <= b.a[0]) {
c.a[c.a[0]] = a[c.a[0]] + 10 - b.a[c.a[0]] - temp;
temp = !(c.a[c.a[0]] / 10);
c.a[c.a[0]++] %= 10;
}
for(int i = --c.a[0]; i > 1; i--)
if(!c.a[i])
c.a[0]--;
else break;
return c;
}
BigInt operator * (const BigInt &b) const {
BigInt c;
c.a[0] = a[0] + b.a[0];
int temp = 0;
for(int i = 1; i <= a[0]; i++) {
c.a[i+b.a[0]-1] = temp;
temp = 0;
for(int j = 1; j <= b.a[0]; j++) {
c.a[i+j-1] += a[i] * b.a[j] + temp;
temp = c.a[i+j-1] / 10;
c.a[i+j-1] %= 10;
}
}
c.a[c.a[0]] = temp;
for(int i = c.a[0]; i > 1; i--)
if(!c.a[i])
c.a[0]--;
else break;
return c;
}
};
ostream& operator << (ostream &out, const BigInt &x) {
for(int i = x.a[0]; i >= 1; i--)
out<<x.a[i];
return out;
}
int n;
BigInt g[105];
int main() {
cin>>n;
g[1] = 3, g[2] = 8;
for(int i = 3; i <= n; i++) g[i] = g[i-1]*3-g[i-2];
cout<<g[n-1]*3;
return 0;
}