BZOJ1002 轮状病毒

基尔霍夫矩阵

*给定一个无向图G,求它生成树的个数t(G);
*
*算法思想:
*(1)G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数;
*(2)G的邻接矩阵A[G]是一个n*n的矩阵,并且满足:如果vi,vj之间有边直接相连,则aij=1,否则为0;
*定义图G的Kirchhoff矩阵C[G]为C[G]=D[G]-A[G];
*Matrix-Tree定理:G的所有不同的生成树的个数等于其Kirchhoff矩阵C[G]任何一个n-1阶主子式的行列式的绝对值;
*所谓n-1阶主子式,就是对于r(1≤r≤n),将C[G]的第r行,第r列同时去掉后得到的新矩阵,用Cr[G]表示;

此题推出f[i]=(f[i-1]*3-f[i-2]+2)

转自:http://www.cnblogs.com/ECJTUACM-873284962/p/7412930.html

根据我们之前的行列式推导也可以轻易地写出规律。

所以直接高精度递推

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct dayi
 4 {
 5     int s[500],l;
 6     void print()
 7     {
 8         for(int i=l;i;--i)
 9         printf("%d",s[i]);
10         return;
11     }
12 }f[105];
13 dayi mul(dayi a,int x)
14 {
15     for(int i=1;i<=a.l;++i)a.s[i]=a.s[i]*x;
16     for(int i=1;i<=a.l;++i)a.s[i+1]+=a.s[i]/10,a.s[i]%=10;
17     if(a.s[a.l+1])++a.l;
18     return a;
19 }
20 dayi work(dayi a,dayi b)
21 {
22     a.s[1]+=2;int j=1;while(a.s[j]>=10)a.s[j+1]++,a.s[j]%=10,j++;
23     for(int i=1;i<=a.l;++i)
24     {
25         a.s[i]-=b.s[i];
26         if(a.s[i]<0)a.s[i]+=10,a.s[i+1]--;
27     }
28     while(!a.s[a.l])a.l--;
29     return a;
30 }
31 int main()
32 {
33     int n;f[1].l=f[2].l=1;f[1].s[1]=1;f[2].s[1]=5;
34     scanf("%d",&n);
35     for(int i=3;i<=n;++i)
36     f[i]=work(mul(f[i-1],3),f[i-2]);
37     f[n].print();
38 }

 

posted @ 2017-12-26 21:35  大奕哥&VANE  阅读(263)  评论(0编辑  收藏  举报