In some countries building highways takes a lot of time... Maybe that's because there are many possiblities to construct a network of highways and engineers can't make up their minds which one to choose. Suppose we have a list of cities that can be connected directly. Your task is to count how many ways there are to build such a network that between every two cities there exists exactly one path. Two networks differ if there are two cities that are connected directly in the first case and aren't in the second case. At most one highway connects two cities. No highway connects a city to itself. Highways are two-way.

Input

The input begins with the integer t, the number of test cases (equal to about 1000). Then t test cases follow. The first line of each test case contains two integers, the number of cities (1<=n<=12) and the number of direct connections between them. Each next line contains two integers a and b, which are numbers of cities that can be connected. Cities are numbered from 1 to n. Consecutive test cases are separated with one blank line.

Output

The number of ways to build the network, for every test case in a separate line. Assume that when there is only one city, the answer should be 1. The answer will fit in a signed 64-bit integer.

Example

Sample input:

Sample output:

Solution

学了一下矩阵树定理,用来求解生成树问题。

矩阵一树定理(matrix-tree theorem)一个计数定理.若连通图G的邻接矩阵为A,将一A的对角线(i,i)元素依次换为节点V的度d(V,),所得矩阵记为M,则M的每个代数余子式相等,且等于G的支撑树的数目.这就是矩阵一树定理.

处理行列式的话,考虑高斯消元,用初等变换把M矩阵处理为上三角矩阵X,那么X的行列式就是对角线系数之积

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define eps 1e-20
using namespace std;
int n,m,A[][],B[][];
double a[][];
void gauss(){
int now=;
for(int i=;i<=n;i++){
int x=now;
while(fabs(a[x][now])<eps && x<=n)++x;
if(x==n+){puts("");return;}
for(int j=;j<=n;j++)
swap(a[now][j],a[x][j]);
for(int j=now+;j<=n;j++){
double x=a[j][now]/a[now][now];
for(int k=;k<=n;k++)
a[j][k]-=a[now][k]*x;
}
++now;
}
double ans=;
for(int i=;i<=n;i++)
ans*=a[i][i];
printf("%.lf\n",fabs(ans));
}
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(A,,sizeof(A));
memset(B,,sizeof(B));
scanf("%d%d",&n,&m);
n--;
while(m--){
int u,v;
scanf("%d%d",&u,&v);
u--;v--;
A[u][u]++;A[v][v]++;
B[u][v]++;B[v][u]++;
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
a[i][j]=A[i][j]-B[i][j];
gauss();
}
return ;
}

[spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)的更多相关文章

  1. spoj104 highways 生成树计数(矩阵树定理)

    https://blog.csdn.net/zhaoruixiang1111/article/details/79185927 为了学一个矩阵树定理 从行列式开始学(就当提前学线代了.. 论文生成树的 ...

  2. BZOJ4031 [HEOI2015]小Z的房间 【矩阵树定理 + 高斯消元】

    题目链接 BZOJ4031 题解 第一眼:这不裸的矩阵树定理么 第二眼:这个模\(10^9\)是什么鬼嘛QAQ 想尝试递归求行列式,发现这是\(O(n!)\)的.. 想上高斯消元,却又处理不了逆元这个 ...

  3. P3317 [SDOI2014]重建 变元矩阵树定理 高斯消元

    传送门:https://www.luogu.org/problemnew/show/P3317 这道题的推导公式还是比较好理解的,但是由于这个矩阵是小数的,要注意高斯消元方法的使用: #include ...

  4. CF917D-Stranger Trees【矩阵树定理,高斯消元】

    正题 题目链接:https://www.luogu.com.cn/problem/CF917D 题目大意 给出\(n\)个点的一棵树,对于每个\(k\)求有多少个\(n\)个点的树满足与给出的树恰好有 ...

  5. 洛谷4208 JSOI2008最小生成树计数(矩阵树定理+高斯消元)

    qwq 这个题目真的是很好的一个题啊 qwq 其实一开始想这个题,肯定是无从下手. 首先,我们会发现,对于无向图的一个最小生成树来说,只有当存在一些边与内部的某些边权值相同的时候且能等效替代的时候,才 ...

  6. Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元

    给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...

  7. SP104 Highways (矩阵树,高斯消元)

    矩阵树定理裸题 //#include <iostream> #include <cstdio> #include <cstring> #include <al ...

  8. 【BZOJ3534】【Luogu P3317】 [SDOI2014]重建 变元矩阵树,高斯消元

    题解看这里,主要想说一下以前没见过的变元矩阵树还有前几个题见到的几个小细节. 邻接矩阵是可以带权值的.求所有生成树边权和的时候我们有一个基尔霍夫矩阵,是度数矩阵减去邻接矩阵.而所谓变元矩阵树实际上就是 ...

  9. uva10766生成树计数(矩阵树定理)

    更正了我之前打错的地方,有边的话G[i][j]=-1; WA了好多次,中间要转成long double才行..这个晚点更新. #include<cstdio> #include<cs ...

随机推荐

  1. 如何在Ubuntu安装*.exe文件

    下载及安装 若你使用 Debian 或者 Ubuntu 之类的发行版,只需要一个命令即可完成安装: apt-get install wine 若你使用的为其他发行版,请访问 http://winehq ...

  2. Android扩展 - 拍照篇(Camera)

    1.调用系统摄像头 1.声明常量和变量 2.按钮点击事件,打开系统摄像头 3.重写onActivityResult事件接收拍照返回 4.生成文件名返回路径 5.保存图片 private static  ...

  3. FJ省队集训DAY2 T2

    思路:我们可以考虑三角剖分,这样问题就变成考虑三角形的选取概率和三角形内有多少个点了. 先用树状数组预处理出三角剖分的三角形中有多少个点,然后用线段树维护,先用原点极角排序,然后枚举i,再以i极角排序 ...

  4. leetcode_Search in Rotated Sorted Array II

    Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...

  5. 【转】Android中BindService方式使用的理解

    原文网址:http://www.cnblogs.com/onlylittlegod/archive/2011/05/15/2046652.html 最近学习了一下Android里面的Service的应 ...

  6. 关于<ul><ol><li>的用法

    <ul>:无序列表 <ol>:有序列表 <li>:行. 想要去掉前面的序号和点可以在<ol>或<ul>style中用list-style: ...

  7. <php>添加数据注意事项

    如果报错信息里有:fetch_all(),肯定是sql语句写错 get传值:<a href="chuli.php?name=1&code=2">处理</a ...

  8. 记录一些Linux C的常用库函数

    我已经受不了每次用的时候去百度了,还百度不出来..... [数字字符串转换篇] atof - convert a string to a double #include <stdlib.h> ...

  9. [Oracle] 使用触发器实现IP限制用户登录

    在Oracle里,不像MySQL那样方便,可以直接在用户上进行IP限制,Oracle要实现用户级别的IP限制,可以使用触发器来迂回实现,下面是一个触发器的例子: create or replace t ...

  10. Thrift的安装和简单演示样例

    本文仅仅是简单的解说Thrift开源框架的安装和简单使用演示样例.对于具体的解说,后面在进行阐述. Thrift简述                                           ...