现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)输出方案数对31011的模

摘自大佬博客:

https://blog.sengxian.com/solutions/bzoj-1016

http://www.cnblogs.com/Y-E-T-I/p/8462255.html#undefined

https://kelin.blog.luogu.org/solution-p4208

https://cnyali-lk.blog.luogu.org/solution-p4208

#include <bits/stdc++.h>
#define fp(i, a, b) for (register int i = a, I = b + 1; i < I; ++i)
#define fd(i, a, b) for (register int i = a, I = b - 1; i > I; --i)
#define go(u) for (register int i = fi[u], v = e[i].to; i; v = e[i = e[i].nx].to)
#define file(s) freopen(s ".in", "r", stdin), freopen(s ".out", "w", stdout)
template <class T>
inline bool cmax(T &a, const T &b) { return a < b ? a = b, : ; }
template <class T>
inline bool cmin(T &a, const T &b) { return a > b ? a = b, : ; }
using namespace std;
const int N = , M = , P = ;
typedef int arr[N];
struct eg
{
int u, v, w;
} e[M];
int n, m, ans = ;
arr fa, bl, vis, g[N], G[N];
vector<int> s[N];
int gf(int u, int *fa) { return fa[u] == u ? u : fa[u] = gf(fa[u], fa); }//find并查集
inline int pls(int a, int b) { return a += b, a >= P ? a - P : a; }//模数不为质数的操作
inline int sub(int a, int b) { return a -= b, a < ? a + P : a; }
inline int det(int n)//返回缩点的生成树个数
{
int a, b, t, f = , tp = ;
fp(i, , n) fp(j, , n) G[i][j] = pls(P, G[i][j]);
fp(i, , n)
{
fp(j, i + , n)
{
a = G[i][i], b = G[j][i];
while (b)
{
t = a / b;
a %= b;
swap(a, b);
fp(k, i, n) G[i][k] = sub(G[i][k], t * G[j][k] % P);
fp(k, i, n) swap(G[i][k], G[j][k]);
f = -f;
}
}
if (!G[i][i])
return ;
tp = tp * G[i][i] % P;
}
return pls(P, f * tp);
}
inline void calc()//合并联通块形成缩点
{
fp(i, , n) if (vis[i])
{
s[gf(i, fa)].push_back(i);
vis[i] = ;
}
fp(i, , n) if (s[i].size() > )
{
int t = s[i].size(), *a = s[i].data();
memset(G, , sizeof G);
fp(j, , t) fp(k, j + , t)
{
int u = a[j - ], v = a[k - ];
if (g[u][v])
{
G[j][k] = G[k][j] = -g[u][v];
G[j][j] += g[u][v], G[k][k] += g[u][v];
}
}
ans = ans * det(t - ) % P;
fp(j, , t) bl[a[j - ]] = i;//属于同一联通块
}
fp(i, , n) s[i].clear(), fa[i] = bl[i] = gf(i, bl);
}
inline bool cmp(const eg &a, const eg &b) { return a.w < b.w; }
int main()
{
#ifndef ONLINE_JUDGE
file("s");
#endif
scanf("%d%d", &n, &m);
fp(i, , n) fa[i] = bl[i] = i;
fp(i, , m) scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
sort(e + , e + m + , cmp);
e[] = e[];
fp(i, , m)
{
//发现不相同的边界点就计算处理
if (e[i].w ^ e[i - ].w)
calc();
//同一权值合并
int u = gf(e[i].u, bl), v = gf(e[i].v, bl);
if (u ^ v)
{
vis[u] = vis[v] = ;
++g[u][v], ++g[v][u];
fa[gf(u, fa)] = gf(v, fa);
}
}
calc();
fp(i, , n) if (bl[i] ^ bl[i - ]) return puts(""), ;
printf("%d", ans);
return ;
}

P4208 [JSOI2008]最小生成树计数的更多相关文章

  1. [洛谷P4208][JSOI2008]最小生成树计数

    题目大意:有$n$个点和$m$条边(最多有$10$条边边权相同),求最小生成树个数 题解:对于所有最小生成树,每种边权的边数是一样的.于是就可以求出每种边权在最小生成树中的个数,枚举这种边的边集,求出 ...

  2. 洛谷P4208 [JSOI2008]最小生成树计数——题解

    题目传送 前置知识:对于同一个图的所有最小生成树,权值相等的边的数量相同. 可以简单证明一下: 我们可以从kruskal的过程考虑.这个算法把所有边按权值大小从小到大排序,然后按顺序看每条边,只要加上 ...

  3. Luogu P4208 [JSOI2008]最小生成树计数

    题意 给定一个 \(n\) 个点 \(m\) 条边的图,求最小生成树的个数. \(\texttt{Data Range:}1\leq n\leq 100,1\leq m\leq 10^4\) 题解 一 ...

  4. bzoj1016 [JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3517  Solved: 1396[Submit][St ...

  5. BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )

    不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...

  6. 1016: [JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6200  Solved: 2518[Submit][St ...

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

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

  8. 【bzoj1016】[JSOI2008]最小生成树计数

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4863  Solved: 1973[Submit][St ...

  9. bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)

    1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等  就是说如果一种方案中权值为1的边有n条 ...

随机推荐

  1. array.js

    // “最后加” concat 连接两个或更多的数组,并返回结果. var a = ['a','b','c']; var b = ['x','y','z']; var c = a.concat(b,t ...

  2. sql server:Monty Hall problem (蒙提霍尔问题)

    --------------------------------------------------------------------- -- Auxiliry Table of Numbers 数 ...

  3. jQ效果:jQuery和css自定义video播放控件

    下面介绍一下通过jquery和css自定义video播放控件. Html5 Video是现在html5最流行的功能之一,得到了大多数最新版本的浏览器支持.包括IE9,也是如此.不同的浏览器提供了不同的 ...

  4. C# 6 元组应用 Part 2:C# 也玩模式匹配

    C# 7给我们带来了一个半吊子的 switch 语句模式匹配,只能简单的匹配类型而已,完全没有什么用处.这里我提供个更好的简单实现,用 C# 6 的 ValueTuple 模拟函数式语言的模式匹配功能 ...

  5. LyX使用中的一些问题

    编译开始产生的检查错误 试用LyX2.3,在2.15中能编译通过的文档,竟然提示错误 The user preamble of your document contains glyphs that a ...

  6. ORM查询之基于对象的正向查询与反向查询

    一.为什么有正向查询和反向查询? 举例有两张表,一张表叫书籍表,一张表叫出版社表,他们关系是一对多的关系,书籍是多,出版社是一,因为一本书应该只有一个出版社对应,而出版社可以有多本书对应. 那么在实际 ...

  7. python 之路初(一):pycharm 安装 和 环境配置 和 中文乱码问题

    从健身和学习中我一体会到坚持的力量.想写写东西的想法已经好久了,就是不知道怎么开始.最近生活开始给我各种攻击和磨练,我从声嘶力竭到沉默到默默坚持自己,改变自己并总结告诉自己:少说多看,看破不说破,宁愿 ...

  8. Linux (Fedora 28) 如何查看 CPU 温度

    机器突然负载有点高,查看CPU 温度的方法: 1.yum install lm_sensors; 2.sensors-detect 3.sensors   这些需要机器具备相应的设备,如果在虚拟机运行 ...

  9. Alpha冲刺! Day3 - 砍柴

    Alpha冲刺! Day3 - 砍柴 今日已完成 晨瑶:补充安卓技能树: review接口文档:看了点七牛云安卓API. 昭锡:没有团队项目相关贡献. 永盛: API 文档基本完成:根据 API 文档 ...

  10. beta版本汇总

    deta版本五天汇总 day1 day2 day3 day4 day5 GitHub地址 前端代码github地址 后端代码github地址 这里说明一下我们队伍的安排风格: 第一天:明确安排前后端的 ...