P4208 [JSOI2008]最小生成树计数
现在给出了一个简单无向加权图。你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)输出方案数对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]最小生成树计数的更多相关文章
- [洛谷P4208][JSOI2008]最小生成树计数
题目大意:有$n$个点和$m$条边(最多有$10$条边边权相同),求最小生成树个数 题解:对于所有最小生成树,每种边权的边数是一样的.于是就可以求出每种边权在最小生成树中的个数,枚举这种边的边集,求出 ...
- 洛谷P4208 [JSOI2008]最小生成树计数——题解
题目传送 前置知识:对于同一个图的所有最小生成树,权值相等的边的数量相同. 可以简单证明一下: 我们可以从kruskal的过程考虑.这个算法把所有边按权值大小从小到大排序,然后按顺序看每条边,只要加上 ...
- Luogu P4208 [JSOI2008]最小生成树计数
题意 给定一个 \(n\) 个点 \(m\) 条边的图,求最小生成树的个数. \(\texttt{Data Range:}1\leq n\leq 100,1\leq m\leq 10^4\) 题解 一 ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
- 1016: [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6200 Solved: 2518[Submit][St ...
- 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)
1016: [JSOI2008]最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树 ...
- 【bzoj1016】[JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4863 Solved: 1973[Submit][St ...
- bzoj1016: [JSOI2008]最小生成树计数(kruskal+dfs)
1016: [JSOI2008]最小生成树计数 题目:传送门 题解: 神题神题%%% 据说最小生成树有两个神奇的定理: 1.权值相等的边在不同方案数中边数相等 就是说如果一种方案中权值为1的边有n条 ...
随机推荐
- [Error] 未发现相关 less 编译器配置,请检查wepy.config.js文件
此错误是由于缺少包引起的 npm install less -d 直接装包即可
- html标签必备
常用快捷键 Ctrl+c 复制 Ctrl+v 粘贴 Ctrl+x 剪切 Ctrl+a 全选 Ctrl+s 保存 Ctrl+z 撤销一步 Windows+d 返回桌面 Windows+e 我的电脑 Wi ...
- Hbase简单配置与使用
一. HBase的 二.基于Hadoop的HBase架构 HBase内置有zookeeper,但一般我们会有其他的Zookeeper集群来监管master和regionserver,Zookeeper ...
- 安装VMwareTool
对于刚刚学习Linux的小白来说,安装VMwareTool工具是一个比较迫切需要,又是些难度的活,下面就做一个简单的介绍. 第一步:点击虚拟机.或者选中需要安装的虚拟机,右键虚拟机,选中安装VMwar ...
- selenium win7+selenium2.0+python环境搭建
win7+selenium2.0+python环境搭建 by:授客 QQ:1033553122 步骤1:下载python 担心最新版的支持不太好,这里我下载的是python 2.7(selenium之 ...
- list中放map的几种方式
package Test; import java.util.*; public class Test { public static void main(String[] args) { //第一种 ...
- system.img镜像转换为system.new.dat + system.transfer.list
android 8.1上面验证,支持所有的android版本,直接放到sdk中执行即可. img2sdat.py #!/usr/bin/env python #coding=utf-8 imp ...
- mysql8 :客户端连接caching-sha2-password问题
在安装mysql8的时候如果选择了密码加密,之后用客户端连接比如navicate,会提示客户端连接caching-sha2-password,是由于客户端不支持这种插件,可以通过如下方式进行修改: # ...
- SVN——Couldn't perform atomic initialization
前言 今天早上刚刚打开我的电脑,就被李总他们告知不能正确用SVN从服务器上下载代码了,然后看问题吧.问题其实也是本文的标题,并不难解决,写下来留个记录,顺便也算是一种分享.问题截图如下: 造 ...
- Postgre SQL连接服务器失败
首先这是登陆postgre sql时提示的错误信息: psql: 无法联接到服务器: Connection refused (0x0000274D/10061) 服务器是否在主机 &qu ...