题目大意:

求最小生成树的数量


曾今的我感觉这题十分的不可做

然而今天看了看,好像是个类模板的题....

我们十分容易知道,记能出现在最小生成树中的边的集合为\(S\)

那么,只要是\(S\)中的边构成的树,一定能构成最小生成树

我们只要预处理哪些可能在最小生成树中即可

打个树剖维护以下就可以了

太懒了,不想打太长,然后就拿并查集随便弄了弄

最后来个矩阵树就行了

\(31011\)不是一个质数,用辗转相除法来消元

复杂度\(O(n^3 \log n)\)


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; #define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --) const int sid = 105;
const int mod = 31011;
inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; }
inline void dec(int &a, int b) { a -= b; if(a < 0) a += mod; }
inline int mul(int a, int b) { return 1ll * a * b % mod; } int n, m, fa[sid];
int E[sid][sid];
struct edge {
int u, v, w;
friend bool operator < (edge a, edge b)
{ return a.w < b.w; }
} e[sid * 10]; inline int find(int o) {
if(o == fa[o]) return o;
else return fa[o] = find(fa[o]);
} inline void init() {
sort(e + 1, e + m + 1);
rep(i, 1, n) fa[i] = i;
for(ri i = 1, j; i <= m; i = j + 1) {
j = i;
while(e[j].w == e[i].w) j ++; j --;
rep(k, i, j) {
int u = find(e[k].u), v = find(e[k].v);
if(u == v) continue;
inc(E[u][u], 1); inc(E[v][v], 1);
inc(E[u][v], mod - 1); inc(E[v][u], mod - 1);
}
rep(k, i, j) {
int u = find(e[k].u), v = find(e[k].v);
if(u == v) continue; fa[u] = v;
}
}
} inline void calc() {
int sign = 1;
n --;
rep(i, 1, n) rep(j, i + 1, n)
while(E[j][i]) {
int t = E[i][i] / E[j][i];
rep(k, i, n) dec(E[i][k], mul(t, E[j][k]));
swap(E[j], E[i]);
sign *= -1;
}
int ans = 1;
rep(i, 1, n) ans = mul(ans, E[i][i]);
if(sign == 1) printf("%d\n", ans);
else printf("%d\n", mod - ans);
} int main() {
cin >> n >> m;
for(int i = 1; i <= m; i ++)
cin >> e[i].u >> e[i].v >> e[i].w;
init(); calc();
return 0;
}

luoguP4208 [JSOI2008]最小生成树计数 矩阵树定理的更多相关文章

  1. [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)

    In some countries building highways takes a lot of time... Maybe that's because there are many possi ...

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

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

  3. 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理

    蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...

  4. BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)

    题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...

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

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

  6. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

    1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...

  7. bzoj1016 [JSOI2008]最小生成树计数——Kruskal+矩阵树定理

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 从 Kruskal 算法的过程来考虑产生多种方案的原因,就是边权相同的边有一样的功能, ...

  8. BZOJ 1016 最小生成树计数(矩阵树定理)

    我们把边从小到大排序,然后依次插入一种权值的边,然后把每一个联通块合并. 然后当一次插入的边不止一条时做矩阵树定理就行了.算出有多少种生成树就行了. 剩下的交给乘法原理. 实现一不小心就会让程序变得很 ...

  9. 【Matrix-tree定理】【并查集】【kruscal算法】bzoj1016 [JSOI2008]最小生成树计数

    题意:求一个图的最小生成树个数. 矩阵树定理:一张无向图的生成树个数 = (度数矩阵 - 邻接矩阵)的任意一个n-1主子式的值. 度数矩阵除了对角线上D[i][i]为i的度数(不计自环)外,其他位置是 ...

随机推荐

  1. PHP autoload自动加载机制

    原文地址: http://www.jb51.net/article/31399.htm 一直不是很明白__autoload()和spl_autoload_register()到底有什么不同,找到了一个 ...

  2. D. Sum in the tree(树形+贪心)

    题目链接;http://codeforces.com/contest/1099/problem/D 题目大意:给出一棵树,每个节点到根节点的路径上经过的所有点的权值之和,其深度为偶数的节点的信息全部擦 ...

  3. MongoDB 查询整理

    查询所有sql:  select * from table_namemongodb:   db.getCollection('期刊论文').find({}) 如上图所示,获取期刊论文collectio ...

  4. Python——脚本(calculator)

    <Python基础教程>(第二版) P123 书中原代码如下: class Calculator: def calculator(self,expression): self.value ...

  5. 牛客红包OI赛 C 小可爱表白

    据说是个公式题. Code #include<cstdio> #include<cstring> #include<algorithm> using namespa ...

  6. github后端开发面试题大集合(一)

    作者:小海胆链接:https://www.nowcoder.com/discuss/3614?type=0&order=0&pos=5&page=0?from=wb来源:牛客网 ...

  7. 配置vuejs加载模拟数据

    [个人笔记,非技术博客] 1.使用前确保安装axios插件,vuejs官方推荐,当然使用其他插件也可以 2.配置dev-server.js var router = express.Router(); ...

  8. SQLServer判断指定列的默认值是否存在,并修改默认值

    SQLServer判断指定列的默认值是否存在,并修改默认值 2008年10月21日 星期二 下午 12:08 if exists(select A.name as DefaultName,B.name ...

  9. 更改Chrome浏览器安装位置的方法

    因为Google Chrome独特的优势,我们很多人都在使用它,但同时我们也会发现它是默认安装在我们的系统盘的,那么是否就不能修改其安装路径了呢?其实不然,这里介绍一种方法,亲测可行. 一.正常安装 ...

  10. 【Codechef】Chef and Bike(二维多项式插值)

    something wrong with my new blog! I can't type matrixs so I come back. qwq 题目:https://www.codechef.c ...