1. 程式人生 > >【BZOJ2467】[中山市選2010]生成樹 矩陣樹定理

【BZOJ2467】[中山市選2010]生成樹 矩陣樹定理

n) 生成樹 scan ans 中山市選 work font 以及 pri

【BZOJ2467】[中山市選2010]生成樹

Description

有一種圖形叫做五角形圈。一個五角形圈的中心有1個由n個頂點和n條邊組成的圈。在中心的這個n邊圈的每一條邊同時也是某一個五角形的一條邊,一共有n個不同的五角形。這些五角形只在五角形圈的中心的圈上有公共的頂點。如圖0所示是一個4-五角形圈。 現在給定一個n五角形圈,你的任務就是求出n五角形圈的不同生成樹的數目。還記得什麽是圖的生成樹嗎?一個圖的生成樹是保留原圖的所有頂點以及頂點的數目減去一這麽多條邊,從而生成的一棵樹。 註意:在給定的n五角形圈中所有頂點均視為不同的頂點。

Input

輸入包含多組測試數據。第一行包含一個正整數T,表示測試數據數目。每組測試數據包含一個整數n

( 2<=N<=100),代表你需要求解的五角形圈中心的邊數。

Output

對每一組測試數據,輸出一行包含一個整數x,表示n五角形圈的生成樹數目模2007之後的結果。

Sample Input

1
2

Sample Output

40

題解:貌似可以直接推式子。。。不過直接上矩陣樹定理也可以做~

#include <cstring>
#include <iostream>
#include <cstdio>
using namespace std;
const int mod=2007;
int n,ans;
int v[410][410];
void work()
{
	memset(v,0,sizeof(v));
	scanf("%d",&n),n<<=2;
	int i,j,k,A,B,t;
	for(i=0;i<n;i++)
	{
		if(i%4)	v[i][i]=2;
		else	v[i][i]=4,v[i][(i+4)%n]=mod-1,v[(i+4)%n][i]=mod-1;
		v[i][(i+1)%n]=mod-1,v[(i+1)%n][i]=mod-1;
	}
	//for(i=0;i<n;i++)	for(j=0;j<n;j++)	printf("%d%c",v[i][j],j==n-1?‘\n‘:‘ ‘);
	for(ans=1,i=1;i<n;i++)
	{
		for(j=i+1;j<n;j++)
		{
			A=v[i][i],B=v[j][i];
			while(B)
			{
				t=A/B,A%=B,swap(A,B);
				for(ans=-ans,k=i;k<n;k++)	v[i][k]=(v[i][k]-v[j][k]*t%mod+mod)%mod,swap(v[i][k],v[j][k]);
			}
		}
		ans=ans*v[i][i]%mod;
	}
	ans=(ans+mod)%mod;
	printf("%d\n",ans);
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)	work();
	return 0;
}

【BZOJ2467】[中山市選2010]生成樹 矩陣樹定理