[bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
Description
现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。由于不同的最小生成树可能很多,所以你只需要输出方案数对31011的模就可以了。
Input
第 一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,000。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10 条。
Output
输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。
Sample Input
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
Sample Output
分析
先回忆一下求解最小生成树的过程:将边排序,贪心添加进当前生成森林中。由Kruskal算法的性质:【传送门】 ,在算法开始处理权值为val的边前,原图会形成若干个连通块,如图所示:
图中的虚线表示原图中所有权值为val的边。通过与Kruskal算法相似的证明,我们可以知道在处理完边数为val的边后,形成的连通分量是一定的。也就是说,在这一过程中不论我们采取怎样的顺序,图中的点集S1,S2,S3一定连通,且这个新的连通块恰好是新的点集的一个最小生成树。
那么,我们如何计算出这一过程可以有多少种连接方式呢?我们先把三个连通块都缩成点:

我们的问题就变成了:在图中选取若干条边使得S1,S2,S3构成一棵树有多少种方案?这就转化为了一个数学问题:一般生成树计数,可以用Matrix-Tree定理来计算。
于是我们就得到了本题的解法:1、将所有边升序排列;2、循环处理每一种权值形成的集合;3、对于同一种权值,利用Matrix-Tree定理求出当前处理的所有边可以产生的那些连通块的连接方式总数,乘入答案;4、将当前边可以产生的连通块缩成点。具体实现细节请看代码中的注释:

, c = getchar();
+ c - , maxm = , mod = ;
, *Mat[], sum;
;i <= x;++i)pre[i] = i;}
;i < M;++i)
;i < ;++i)
];;
;i < n;++i){
;j < n;++j){
], block[], cnt;
;
,j = ;i < len;++i){
] = tmp[];
;i < j;++i)
])block[cnt++] = tmp[i]; ;i < cnt;++i);j < cnt;++j)
Mat[i][j] = ;
tmpS.init(cnt);
;i < len;++i){
A[i].u = index(A[i].u);
A[i].v = index(A[i].v); ++Mat[A[i].v][A[i].v];
--Mat[A[i].v][A[i].u];
tmpS.link(A[i].u, A[i].v);
}
;i < cnt;++i)
))){
++Mat[a][a], ++Mat[b][b];
tmpS.link(a, b);
}
Ans = Ans * det(cnt) % mod;
}
inline , j = , t;
)calc(E + i, j - i);
i = j++;
}
)printf( printf( }
freopen( #ifndef ONLINE_JUDGE
freopen( freopen( init();
work();
;
}
Kruskal + Matrix Tree定理
[bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)的更多相关文章
- bzoj1016 [JSOI2008]最小生成树计数——Kruskal+矩阵树定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 从 Kruskal 算法的过程来考虑产生多种方案的原因,就是边权相同的边有一样的功能, ...
- [BZOJ1016] [JSOI2008] 最小生成树计数 (Kruskal)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
- [BZOJ1016][JSOI2008]最小生成树计数(结论题)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1016 分析: 首先有个性质:如果边集E.E'都可以表示一个图G的最小生成树(当然E和E ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数
题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
一直以为这题要martix-tree,实际上因为有相同权值的边不大于10条于是dfs就好了... 先用kruskal求出每种权值的边要选的次数num,然后对于每种权值的边2^num暴搜一下选择的情况算 ...
- BZOJ1016:[JSOI2008]最小生成树计数(最小生成树,DFS)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
随机推荐
- NYOJ 138 找球号(二) (哈希)
题目链接 描述 在某一国度里流行着一种游戏.游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是&qu ...
- spring-boot 属性定义和配置bean
自定义bean属性 1.定义bean属性 // 通过@ConfigurationProperties加载properties文件内的配置, // 通过prefix属性指定properties的配置的前 ...
- 环境变量配错了 command not found
一般就是忘记在PATH 前面加$ 1.可以用whereis或者which命令查看一下有没有这个命令 具体执行which lswhereis ls 2.系统环境变量导致的问题解决方案: exportPA ...
- KVC, KVO 实现原理
Key-Value Coding: 键值编码 (KVC) 方法调用: // 对象属性 // 类似: Person -> name setValue: forKey: // 对象的属性或者 属性的 ...
- 当array_filter函数的callback留空时 他会过滤掉所有键值为false的键
当array_filter函数的callback留空时 他会过滤掉所有键值为false的键
- hdu 1849(巴什博弈)
Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- MySql学习笔记——触发器
今天又学习了一下mysql触发器的相关知识,对此做了一些笔记和总结. 定义及作用 触发器是一个被指定关联到一个表的数据对象,触发器不需要调用,当对一个表的特别事件出现时,它就会被激活.触发器的代码也是 ...
- 用JDK自带的监控工具jconsole来监控程序运行
工具目录:C:\Program Files\Java\jdk1.6.0_06\bin\jconsole.exe 效果如下:监控类ThreadPoolExecutorTest 的运行 选择我们运行的程序 ...
- postgresql 数据导入导出
[转] 分类: postgresql2013-06-09 10:21 2486人阅读 评论(0) 收藏 举报 一.导出数据库及具体表 1.导出数据库:方式一:pg_dump -U postgres ...
- Codeforces Round #278 (Div. 1) D - Conveyor Belts 分块+dp
D - Conveyor Belts 思路:分块dp, 对于修改将对应的块再dp一次. #include<bits/stdc++.h> #define LL long long #defi ...