【SPOJ】Highways(矩阵树定理)

【SPOJ】Highways(矩阵树定理)

题面

Vjudge
洛谷

题解

矩阵树定理模板题

无向图的矩阵树定理:
对于一条边\((u,v)\),给邻接矩阵上\(G[u][v],G[v][u]\)加一
对于一条边\((u,v)\),给度数矩阵上\(D[u][u],D[v][v]\)加一
定义霍尔基夫矩阵\(C=D-G\)

将基尔霍夫矩阵去除任意一行和任意一列之后,
得到一个\((n-1)*(n-1)\)的行列式\(C\)
求解这个行列式的值,最后的\(|det(C)|\)就是结果

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define RG register
#define MAX 13
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
int n,m;
ll a[MAX][MAX];
int main()
{
	int T=read();
	while(T--)
	{
		n=read();m=read();
		memset(a,0,sizeof(a));
		while(m--)
		{
			int u=read(),v=read();
			a[u][u]++;a[v][v]++;
			a[u][v]--;a[v][u]--;
		}
		--n;ll ans=1;
		for(int i=1;i<=n;++i)
		{
			for(int j=i+1;j<=n;++j)
				while(a[j][i])
				{
					ll t=a[i][i]/a[j][i];
					for(int k=i;k<=n;++k)a[i][k]-=t*a[j][k],swap(a[i][k],a[j][k]);
					ans=-ans;
				}
				ans*=a[i][i];
		}
		printf("%lld\n",ans);
	}
	return 0;
}

posted @ 2018-04-21 09:16  小蒟蒻yyb  阅读(452)  评论(0编辑  收藏  举报