生成树计数[矩阵树算法Matrix-tree](caioj1227)

版权声明:作为一个蒟蒻,转载时请通知我这个蒟蒻 https://blog.csdn.net/zyszlb2003/article/details/89402887

题面描述

一个无限图有 n n 个点,m条边 n 1 m ) (n-1\le m) ,求生成树的方案数。
【输入格式】
第一行两个整数 n ( 2 n 15 n 1 m n ( n + 1 ) / 2 ) n(2 ≤ n ≤15,n-1 \le m \le n*(n+1)/2 )
下来 m m 行,每行两个整数 x x y y ,表示一条无向边。
【输出格式】
一行一个整数,表示生成树的方案数。
【样例输入】
4 6
1 2
2 3
3 4
4 1
1 3
2 4
【样例输出】
16

思考

没思路,死记就好,现不会

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<bitset>
#define eps 1e-10
using namespace std;
const int N=16;
int d[N][N],a[N][N];double c[N][N];int n,m;
void gauss()
{
	for(int i=1;i<=n;i++)
	{
		int x=i;
		while(fabs(c[x][i])<eps&&x<=n)x++;
		if(x==n+1){puts("0");return ;}
		for(int j=1;j<=n;j++){double t=c[i][j];c[i][j]=c[x][j];c[x][j]=c[i][j];}
		for(int k=n;k>=i+1;k--)
		{
			for(int j=n;j>=i;j--)c[k][j]-=c[k][i]/c[i][i]*c[i][j];
		}
	}
	double ans=1;
	for(int i=1;i<=n;i++)ans*=c[i][i];
	ans=fabs(ans);printf("%.0lf",ans);
}
int main()
{
	scanf("%d%d",&n,&m);n--;
	for(int i=1;i<=m;i++)
	{
		int x,y;scanf("%d%d",&x,&y);
		a[x][y]++;a[y][x]++;d[x][x]++;d[y][y]++;
	}
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)c[i][j]=d[i][j]-a[i][j];
	gauss();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zyszlb2003/article/details/89402887