Organising the Organisation(uva10766)(生成树计数)

Input

Output

Sample Input
5 5 2
3 1
3 4
4 5
1 4
5 3
4 1 1
1 4
3 0 2
Sample Output
3
8
3
题意:
有一张图上有\(n\)个点,两两之间有一条边,现在切断\(m\)条边,求剩下的图中有多少种不同的生成树。
题解:
生成树计数
做这道题,需要三个预备知识:
\(Kirchhoff\)矩阵
首先先构造两个矩阵
度数矩阵D:是一个\(N×N\)的矩阵,其中
\(D[i][j]=0(i≠j)\),\(D[i][i]=i\)号点的度数
邻接矩阵A:是一个\(N×N\)的矩阵,其中
\(A[i][i]=0,A[i][j]=A[j][i]=i\),\(j\)之间的边数
然后\(Kirchhoff\)矩阵\(K=D-A\)
举个例子,对于如下的无向图,三个矩阵分别为:(图片来源于网络)

行列式\(det(K)\)及其求法
考虑对于原矩阵\(K\),我们可以得到其行列式的求和式:
\(\det(A) = \sum_{\sigma \in S_n} sgn(\sigma) \prod_{i=1}^n a_{i,\sigma(i)}\)
其中\(S_n\)是指全排列的集合,\(\sigma\)就是一个全排列,如果\(\sigma\)的逆序对对数为偶数,则\(sgn(\sigma)=1\)否则\(=-1\)
然后我们可以用\(n!\)左右的算法解决了,但这绝对会TLE啊!!!
让我们来研究一下行列式的性质(我就列了几条有用的):
- 性质.1 互换矩阵的两行(列),行列式变号。
- 性质.2 如果该矩阵为一三角形矩阵。则该矩阵的行列式等于A的对角元素的乘积。
- 性质.3 如果把矩阵的某一行(列)加上另一行(列)的k倍,则行列式的值不变。
- 性质.4 如果矩阵有两行(列)成比例(比例系数k),则行列式的值为0。
- 性质.5 互换矩阵的两行(列),行列式变号。
结合这几个性质,我们可以很明显的看出可以用高斯消元优化了,复杂度为\(O(n^3)\)。
\(Matrix-Tree\)定理:
- 对于一个无向图G,它的生成树个数等于其\(Kirchhoff\)矩阵任何一个n-1阶主子式的行列式的绝对值。
好吧其实我没看懂这个定理,但经过一番感性理解,大概就是这个意思:
- 我们把\(Kirchhoff\)矩阵的第\(i\)行和第\(i\)列去掉,剩下矩阵的行列式的绝对值就是生成树的数量。
其中\(i\)为\(1\)~\(n\)中任意一个数(真的是任意一个就可以了),为了方便这题我们直接设它为n就行了。
有了这几个预备知识后,这一题就可以做了。
上代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll A[60][60],K[60][60];
ll tree_sum(int n){
ll ret=1;
for(int i=1;i<=n;++i){
if(!K[i][i]){
bool b=0;
for(int j=i+1;j<=n;++j){
if(K[j][i]){
b=1;
for(int k=1;k<n;++k){
swap(K[i][k],K[j][k]);
}ret=-ret;
break;
}
}
if(!b)return 0;
}
for(int j=i+1;j<=n;++j){
while(K[j][i]){
ll t=K[i][i]/K[j][i];
for(int k=i;k<=n;++k){
K[i][k]-=t*K[j][k];
swap(K[i][k],K[j][k]);
}
ret=-ret;
}
}ret*=K[i][i];
}return ret;
}
int main(){
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k)){
memset(A,0,sizeof A);
memset(K,0,sizeof K);
for(int i=1;i<=m;++i){
int x,y;
scanf("%d%d",&x,&y);
A[x][y]=A[y][x]=1;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(i!=j&&!A[i][j]){
K[i][i]++;
K[i][j]--;
}
}
}--n;
ll ans=tree_sum(n);
printf("%lld\n",ans);
}
}
Organising the Organisation(uva10766)(生成树计数)的更多相关文章
- 「UVA10766」Organising the Organisation(生成树计数)
BUPT 2017 Summer Training (for 16) #6C 题意 n个点,完全图减去m条边,求生成树个数. 题解 注意可能会给重边. 然后就是生成树计数了. 代码 #include ...
- Uva 10766 Organising the Organisation (Matrix_tree 生成树计数)
题目描述: 一个由n个部门组成的公司现在需要分层,但是由于员工间的一些小小矛盾,使得他们并不愿意做上下级,问在满足他们要求以后有多少种分层的方案数? 解题思路: 生成树计数模板题,建立Kirchhof ...
- uva10766生成树计数
此类题是给定一个无向图,求所有生成树的个数,生成树计数要用到Matrix-Tree定理(Kirchhoff矩阵-树定理) G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0:当i ...
- uva10766生成树计数(矩阵树定理)
更正了我之前打错的地方,有边的话G[i][j]=-1; WA了好多次,中间要转成long double才行..这个晚点更新. #include<cstdio> #include<cs ...
- UVA10766:Organising the Organisation(生成树计数)
Organising the Organisation 题目链接:https://vjudge.net/problem/UVA-10766 Description: I am the chief of ...
- 生成树的计数(基尔霍夫矩阵):UVAoj 10766 Organising the Organisation SPOJ HIGH - Highways
HIGH - Highways In some countries building highways takes a lot of time... Maybe that's because th ...
- UVa 10766 Organising the Organisation (生成树计数)
题意:给定一个公司的人数,然后还有一个boss,然后再给定一些人,他们不能成为直属上下级关系,问你有多少种安排方式(树). 析:就是一个生成树计数,由于有些人不能成为上下级关系,也就是说他们之间没有边 ...
- kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数
第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...
- 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)
1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1766 Solved: 946[Submit][Status ...
随机推荐
- vue.js项目打包上线
最近一直坚持每个月写一个小的vue.js 开发的项目,最后开发完成后想到很久之前给别人回答的一个问题:vue的项目如何上线,当时有千奇百怪的回答,我在想,这些人都是肿了么,vue的官方都说了,这个框架 ...
- 社交类APP原型模板分享——Tinder
Tinder是国外的一款手机交友APP,作用是基于用户的地理位置,每天“推荐”一定距离内的四个对象,根据用户在 Facebook 上面的共同好友数量.共同兴趣和关系网给出评分,得分最高的推荐对象优先展 ...
- python函数、装饰器、迭代器、生成器
目录: 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象: 函数是第一类对象,即函数可以当作数据传递 ...
- 2018.10.05 NOIP模拟 相遇(dfs序+lca)
传送门 考虑到两条路径相交的条件: 设两条路径为a,ba,ba,b. 则要么aaa路径的lcalcalca在bbb上. 要么bbb路径的lcalcalca在aaa上. 因此我们维护两棵树. 分别支持路 ...
- Cygwin工具的简单使用
简介 从使用角度来看:Cygwin就是一个windows软件,该软件就是在windows上仿真linux操作系统.简言之,cygwin是一个在windows平台上运行的 linux模拟环境,使用一个D ...
- UVa 11491 Erasing and Winning (贪心,单调队列或暴力)
题意:给一个数字(开头非0),拿掉其中的d个数字,使剩下的数字最大(前后顺序不能变). 析:拿掉d个数字,还剩下n-d个数字.相当于从n个数字中按先后顺序选出n-d个数字使组成的数字最大,当然采用窗口 ...
- UVa 11384 Help is needed for Dexter (递归)
题意:给定一个n表示1到n的序列,让你用最小的步数把这个序列都变为0,每个操作可以从序列中选择一个或多个个,同时减掉一个正整数,求最少的步数. 析:一看这个题,感觉挺高深的,但是静下心来想想,其实挺简 ...
- oss上传文件夹-cloud2-泽优软件
泽优软件云存储上传控件(cloud2)支持上传整个文件夹,并在云空间中保留文件夹的层级结构,同时在数据库中也写入层级结构信息.文件与文件夹层级结构关系通过id,pid字段关联. 本地文件夹结构 文件 ...
- 5) mvn archetype:generate
获取帮助 mvn -h 命令格式 usage: mvn [options] [<goal(s)>] [<phase(s)>] -D,--define <arg> D ...
- 多线程中使用curl致coredump问题
coredump时的调用栈: #0 0x081eff2c in addbyter () #1 0x081f05b8 in dprintf_formatf () #2 0x081f15cf in ...