bzoj2467 生成树 Matrix-tree定理

来源:互联网 发布:淘宝售假扣保证金 编辑:程序博客网 时间:2024/05/23 19:46

http://www.lydsy.com/JudgeOnline/problem.php?id=2467

不知道为什么,一看到这道题就果断想到了Maxtrix-tree定理,然后搞kirchhoff矩阵。


but首先我需要搞懂样例,测试了3种情况才搞懂样例。

样例是两个五边形圈共用一条边,所有中心多边形的点都搞成度数为4,并且和周围的+1,-1都有边且累加-1(为了2的情况不写特判)。


然后YY处理每个五边形剩下的3个点,然后我就列出来了(码量可能有点长)


然后就随便舍弃了最后一行一列,求行列式的值就好了。

(PS:我忘记了取模,忘记了取模,忘记了取模~~~~                     并且kirchhoff矩阵有负数,我忘了搞这个~~~~~    最后一步测试100的时候是个负数,然后想起来了没有把它调成正数(行列式变换有可能变成负数)   然后+p之后mod p就过了,233~~~)


#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#include<cmath>using namespace std;int T;int n;int f[1020][1020];int cnt;void work(){for(int i=1;i<=cnt;i++){for(int j=1;j<=cnt;j++)f[i][j]=(f[i][j]+2007)%2007;}int det=1;for(int i=1;i<=cnt;i++){for(int j=i+1;j<=cnt;j++){while(f[j][i]){int t=-f[i][i]/f[j][i];for(int k=i;k<=cnt;k++)f[i][k]=(f[i][k]+t*f[j][k])%2007;for(int k=i;k<=cnt;k++)swap(f[i][k],f[j][k]);det=-det;}}if(f[i][i]==0){printf("0\n");return ;}det*=f[i][i];det%=2007;}det+=2007;det%=2007;printf("%d\n",det);}int main(){scanf("%d",&T);while(T--){memset(f,0,sizeof(f));scanf("%d",&n);cnt=n;    for(int i=1;i<=n;i++)    {    f[i][i]+=4;    f[i][(i+1<=n)?i+1:1]+=-1;    f[i][(i-1)>=1?i-1:n]+=-1;    }    for(int i=1;i<=n;i++)    {    cnt++;    f[i][cnt]=f[cnt][i]+=-1;    f[cnt][cnt]+=2;    f[cnt][cnt+1]+=-1;    f[cnt+1][cnt]+=-1;        cnt++;    f[cnt][cnt]+=2;    f[cnt][cnt+1]+=-1;    f[cnt+1][cnt]+=-1;        cnt++;    f[cnt][cnt]+=2;    f[cnt][(i+1)<=n?i+1:1]+=-1;    f[(i+1)<=n?i+1:1][cnt]+=-1;    }    cnt--;    work();}return 0;}


0 0
原创粉丝点击