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