Description

在图论中,树的定义是连通且无环的无向图。对于一棵有 nn 个节点且节点从 11 到 nn 编号的树,它的 Prufer 序列是一个唯一的长为 n−2n−2 的标号序列。 Prufer 序列的构造方法:每次删除树中标号最小的叶子节点(即度为 11 的节点),将该点的邻居加到当前 Prufer 序列的末尾,直到只剩两个节点为止。

例子:

给定一个 nn 个顶点(从 11 到 nn 标号), mm 条边的无向图 GG(GG 中无重边或自环)。随机选择 GG 的一棵生成树,计算他的 Prufer 序列的和 SS,重复元素只算一次。 请计算随机变量 SS 的期望。注意,GG 的生成树或某棵生成树的 Prufer 序列都可能不存在,这种情况下,我们认为随机变量 SS 的值为 00。

为了避免精度问题, 算出实际的期望值乘以图 GG 的不同生成树的数目以后的值即可。 这个值可能很大,请输出它对 109+7109+7 取模以后的值。

Input

每个输入文件包含多组测试数据。输入文件的第一行是测试数据组数 TT (T≤10T≤10)。 对于每组测试数据,第一行是两个整数 n,mn,m (3≤n≤100,0≤m≤(n−1)n23≤n≤100,0≤m≤(n−1)n2 ),分别是图的点数和边数;接下来 mm 行,每行包含两个整数 u,vu,v(1≤u,v≤n1≤u,v≤n,u≠vu≠v),表示图中的一条边。

Output

输出 TT 行,每行是对应的答案。

Sample Input

1
3 3
1 2
2 3
1 3

Sample Output

6

题目大意:求所有生成树的prufer序列和(prufer中有重复序列的只算一次!!!)

题解:

这样的话,对于每一颗生成树,我们可以把所有的点全都加进去,然后再减去叶子结点的和。

我们不可能找到所有的生成树然后一个一个的计算,因此我们用矩阵树定理来做。

我们先计算图所有的点的和,并且乘以生成树的数量,把他们放在sum里。然后再把所有的叶子结点减去,就好了

如果一个叶子节点出现在一颗子树里,那么把这个点去掉,仍然可一得到图的该生成树,而如果这个点是内部节点就不行了。

注意:如果这个叶子节点的度不为1,那么要用这个叶子节点的度数乘以生成树的数量,才是这个叶子节点对应生成树的个数。

sum -= 去掉该节点生成树的数量*该节点的度*该节点的值。

最后得到的sum就是答案

代码:

#include<iostream>。
#include<cmath>
#include <cstring>
using namespace std;
#define zero(x)((x>0? x:-x)<1e-15)
#define int long long
int const MAXN = 105;
const int mod = 1e9 + 7;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int g[103][103];
int d[105];
int n, m;
int det(int a[MAXN][MAXN], int n){ int s=0;for(int i=0; i<n; i++){ int r=i; for(; r<n; r++)    // error-prone if(a[r][i]) break; if(r==n+1) return 0; if(r!=i){ s^=1; for(int j=i; j<n; j++) swap(a[i][j], a[r][j]); } for(int j=i+1; j<n; j++){ int x=i, y=j; for(; a[y][i]; ){ // print(a, n); int t=a[y][i]/a[x][i]; if(t){ for(int k=i; k<n; k++){ a[y][k] -= t*a[x][k]%mod; a[y][k] %= mod; } if(a[y][i]==0) break; } swap(x, y); } if(x!=i){ for(int k=i; k<n; ++k) swap(a[x][k], a[y][k]); s ^= 1; } } } int res=1; for(int i=0; i<n; i++) res*=a[i][i], res%=mod; if(s){ res=-res; }if(res < 0) res+=mod; return res;
} void prep(int n,int x)
{for(int i = 0;i < n;i++){for(int j = 0;j < n;j++){a[i][j] = (i == j)?d[i]-g[i][x]:-g[i][j];}}if(x + 1){for(int i = 0;i < n;i++) a[x][i] = a[i][x] = 0;a[x][x] = 1;}
}main()
{   int cas;scanf("%lld", &cas);while (cas--) {memset(g,0,sizeof(g));memset(d,0,sizeof(d));memset(a,0,sizeof(a));memset(b,0,sizeof(b));scanf("%lld%lld", &n,&m);for(int i = 0;i < m;i++){int u,v;scanf("%lld%lld",&u,&v);u--,v--;d[u]++;d[v]++;g[u][v] = g[v][u] = 1;}prep(n,-1);int sum = det(a,n-1)*((1+n)*n/2) % mod;for(int i = 0;i < n-1;i++){prep(n,i);sum = (sum - (i+1)*d[i] % mod * det(a,n-1) % mod + mod)%mod;//cout<<':'<<sum<<endl;}prep(n,n-1);sum = (sum - n*d[n-1] % mod * det(a,n-2) % mod + mod)%mod;cout<<sum<<endl;}return 0;
}

Prufer序列 生成树定理相关推荐

  1. 最小生成树、矩阵树定理、Prufer序列总结

    Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...

  2. 解题报告(八) prufer 序列与 Cayley 公式(ACM / OI)超高质量题解

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  3. 模板:Prufer序列

    所谓 Prufer 序列,就是 Prufer 发明的序列. (逃) 前言 优雅的神奇魔术. 看名字很高大难,但实际上是高大清(小清新). 很简单的建立起树与序列之间的双射,且这个序列的性质非常良好,且 ...

  4. [XXSY] 构树(prufer序列,树上连通块DP)

    传送门 CayleyCayleyCayley公式:一个完全图有nn−2n^{n-2}nn−2棵无根生成树(可用prufer序列证明) 扩展CayleyCayleyCayley公式:被确定边分为大小为a ...

  5. 【XSY2519】神经元 prufer序列 DP

    题目描述 有\(n\)点,每个点有度数限制,\(\forall i(1\leq i\leq n)\),让你选出\(i\)个点,再构造一棵生成树,要求每个点的度数不超过度数限制.问你有多少种方案. \( ...

  6. Prufer序列相关

    最近做到一些题,用到了Prufer序列,挺有用的,在这里学习一下. 描述 Prufer数列是无根树的一种数列,通过一个Prufer序列可以唯一表示一棵顶点带标号的无根树,点数为n的树转化来的Prufe ...

  7. 曼哈顿距离与切比雪夫距离的转化及prufer序列

    目录 曼哈顿距离与切比雪夫距离的相互转化 prufer序列 1. 曼哈顿距离 与 切比雪夫距离 的相互转化 曼哈顿距离 |x1−x2|+|y1−y2|=max(x1−x2+y1−y2,x1−x2−y1 ...

  8. 树的计数(prufer序列 或 purfer序列)

    题解 首先我们要知道一条性质,prufer序列中的某个点出现次数为该点在树中度数-1 感性理解一下,其实按照prufer序列求法自己推一下就出来了 设题目里给的度为$d[]$ 先将所有的d-- 然后按 ...

  9. 【XSY1295】calc n个点n条边无向连通图计数 prufer序列

    题目大意 求\(n\)个点\(n\)条边的无向连通图的个数 \(n\leq 5000\) 题解 显然是一个环上有很多外向树. 首先有一个东西:\(n\)个点选\(k\)个点作为树的根的生成森林个数为: ...

最新文章

  1. Postman增删改查接口测试
  2. 戈登贝尔奖获得者张林峰:当AI遇上物理模型,会有怎样的质变? | 智源专访...
  3. 【S1官方核心】18128核心纯净雅黑H大全力打造的1.9精品
  4. sklearn支持gpu_Keras Sklearn随机搜索GPU OOM
  5. 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t
  6. 个人博客代码_Jekyll + Github Pages 搭建个人免费博客
  7. 安装配置mac版_全面战争三国 Mac版Mod安装指南
  8. JAVA怎么创建被继承的类_Java入门之类的继承
  9. 教育学考研跨考计算机,某985计算机专业,想要三跨北师大教育学,会不会很难?...
  10. 实习三个月的地一个完整项目总结
  11. 微信小程序 - WXML语法与HTML比较
  12. java工程师认证_Java工程师认证工信部考试.doc
  13. 只有英语四级和计算机二级,通过英语四级和计算机二级用英语怎么说
  14. ReentrantLock使用及其原理解析
  15. 吴恩达机器学习——反向传播算法
  16. 电子设计硬件可靠性设计----总结2
  17. 计算机毕业设计之java+ssm企业员工考勤系统
  18. 即第一个字母变成第26个字母,第i个字母变成第(26-i+1)个字母,非字母字符不变。要求编程将密码译回原文,并打印出密码和原文。
  19. 打印机无法打印,配置端口显示错误?
  20. 统计文件中每个字母的个数

热门文章

  1. java 中符号_谁能告诉我java中符号的用法,见代码
  2. vector的基本用法 (详解 + 代码演示)
  3. C++实现各种选择排序(简单选择排序,堆排序)
  4. oracle 取英文排序,Oracle中中文、数字,英文混杂形式的字段进行排序的方法
  5. 火焰效果材质实现_「游戏开发」使用Unity实现魔法火焰效果
  6. 监督学习和非监督学习
  7. K. Easy Sigma(类欧几里得)
  8. Codeforces Round #653 (Div. 3)(A, B, C, D, E1详解)
  9. P2770 航空路线问题(网络流)
  10. CodeForces - 1189B Number Circle