【BZOJ】【P2467】【中山市选2010】【生成树】【题解】【矩阵树定理+高斯消元+打表】

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

建图后直接上矩阵树定理

打个表就行了

A掉之后发现自己傻逼了……ans=4n*5^(n-1)

就算是欧几里得高斯消元的练手吧

AC代码:

#include<bits/stdc++.h>
using namespace std;
int anss[]={0,0,40,300,2000,458,741,1981,1285,1458,518,842,1491,1888,1675,1662,836,929,432,1165,850,1452,1298,764,1281,1738,1411,765,473,1661,771,304,1828,645,890,803,1836,292,1174,426,1001,1367,687,793,790,117,1490,1940,213,1798,613,1320,1889,1946,333,841,85,1902,839,980,867,226,655,900,653,86,591,1753,748,1788,1187,1289,1278,625,391,327,1523,1034,363,1864,1537,882,500,1013,1644,1150,505,384,1250,893,1764,1336,1372,390,1712,1349,795,316,1348,1566,23,};
int main(){
	int T,n;
	cin>>T;
	while(T--){
		cin>>n;
		cout<<anss[n]<<endl;
	}
	return 0;
}

打表程序:

#include<bits/stdc++.h>
using namespace std;
const int maxn=405;
int n,p=2007,tot;
int A[maxn][maxn];
int Gauss(){
	int ans=-1;n--;
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)A[i][j]%=p;	
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++)while(A[j][i]){
			int t=A[i][i]/A[j][i];
			for(int k=i;k<=n;k++)A[i][k]=(A[i][k]-A[j][k]*t)%p;
			for(int k=i;k<=n;k++)swap(A[i][k],A[j][k]);ans=-ans;
		}ans=ans*A[i][i]%p;
	}return (ans+p)%p;
}
void add(int u,int v){A[u][v]++;A[v][u]++;}
void build(){
	tot=n;
	for(int i=1;i<=n;++i)add(i,i+1>n?1:i+1);
	for(int i=1;i<=n;++i){
		int u=i,v=i+1>n?1:i+1;
		add(u,tot+1);
		add(tot+1,tot+2);
		add(tot+2,tot+3);
		add(tot+3,v);
		tot+=3;
	}n=tot;
	for(int i=1;i<=tot;i++)for(int j=1;j<=tot;j++)if(i!=j)A[i][i]-=A[i][j];	
}
int main(){
	freopen("2746.out","w",stdout);
	for(int i=2;i<=100;i++){
		cerr<<i<<endl;
		n=i;
		memset(A,0,sizeof A);
		build();
		cout<<Gauss()<<","<<endl;
	}
	return 0;
}


你可能感兴趣的:(bzoj)