题目大意:
有N个节点,某些节点之间可以连边,求有多少种方案可以使任意两点间有唯一路径
【分析】
生成树计数问题:Marix-Tree定理
具体含义:http://download.csdn.net/detail/u012274244/6638281
【代码】
/*
ID:Ciocio
LANG:C++
DATE:2013-11-30
TASK:SPOJ-104 Highways
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 20
#define LL long long
int N,M,degree[MAXN];
LL C[MAXN][MAXN];
void _init()
{
scanf("%d%d",&N,&M);
for(int i=1;i<=M;i++)
{
int x,y;
scanf("%d%d",&x,&y);
C[x][y]=C[y][x]=-1;
degree[x]++;
degree[y]++;
}
}
LL _det(LL a[MAXN][MAXN],int n)
{
LL ret=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]=(a[i][k]-a[j][k]*t);
swap(a[i][k],a[j][k]);
}
ret*=(-1);
}
if(!a[i][i]) return 0;
ret*=a[i][i];
}
return abs(ret);
}
void _solve()
{
for(int i=1;i<=N;i++) //C即为原图的Kirchhoff矩阵
C[i][i]=degree[i];
printf("%lld\n",_det(C,N-1)); //对矩阵C求一次N-1阶主子式的行列式绝对值
}
int main()
{
int Case;scanf("%d",&Case);
while(Case--)
{
memset(C,0,sizeof(C));
memset(degree,0,sizeof(degree));
_init();
_solve();
}
return 0;
}