
有一个连通图,中心有一个点连向外面的N个顶点,外围的每个顶点与相邻两点有连边。求最小生成树个数。
基尔霍夫矩阵。
根据数据范围,显然可以用基尔霍夫矩阵搞定。当然我用的是递推,a[n]=3*a[n-1]-a[n-2]+2.递推求解即可。注意写高精度。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include<cstring> #define CK 10000 using namespace std; int n; class { public: int len; int s[1010]; void clean(void){memset(s,0,sizeof(s)); len=1;} void write(void){printf("%d",s[len-1]); for (int i=len-2;i>=0;i--) printf("%.4d",s[i]);} }; Marvolo a,b,c; inline Marvolo operator *(int x,Marvolo y){ int i=0; for (i=0;i<=y.len-1;i++) y.s[i]*=3; for (i=0;i<y.len||y.s[i]>0;i++){ y.s[i+1]+=y.s[i]/CK; y.s[i]%=CK; } y.len=i; return y; } inline Marvolo operator -(Marvolo x,Marvolo y){ int i=0; for (i=0;i<y.len;i++) x.s[i]-=y.s[i]; for (i=x.len-1;i>=1;i--) x.s[i]-=1,x.s[i-1]+=CK; for (i=0;i<x.len||x.s[i]>0;i++){ x.s[i+1]+=x.s[i]/CK; x.s[i]%=CK; } x.len=i; return x; } inline Marvolo operator +(Marvolo x,int y){ int i=0; x.s[0]+=2; for (i=0;i<x.len||x.s[i]>0;i++){ x.s[i+1]+=x.s[i]/CK; x.s[i]%=CK; } x.len=i; return x; } int main(){ a.len=1; a.s[0]=1; b.len=1; b.s[0]=5; scanf("%d",&n); if (n==1) {printf("1n"); goto END;} else if (n==2) {printf("5n"); goto END;} for (int i=3;i<=n;i++){ c=3*b; c=c-a; c=c+2; a=b; b=c; } b.write(); END: return 0; }
|
连接
COGS
BZOJ
近期评论