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条 ...
随机推荐
- returnFunc.js
var cyn = function(){ console.log("one") return function(){ console.log("two") } ...
- 【代码笔记】Web-JavaScript-JavaScript输出
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- Apex 的 Trigger 类简介
Apex Triggers Apex 触发器(Apex Triggers)是一种特殊的 Apex 类.它的主要作用是在一条记录被插入.修改.删除之前或之后自动执行一系列的操作.每一个 Trigger ...
- 《ASP.NET MVC企业实战》(二) MVC开发前奏
在上一篇“<ASP.NET MVC企业级实战>(一)MVC开发前奏”中记录了作者介绍的一些比较实用的VS使用方法以及C#2.0中添加的新特性.本篇继续大概了解之后版本的一些新特性. ...
- spring BeanFactory及ApplicationContext中Bean的生命周期
spring bean 的生命周期 spring BeanFactory及ApplicationContext在读取配置文件后.实例化bean前后.设置bean的属性前后这些点都可以通过实现接口添加我 ...
- (后端)Java中关于金额大小写的工具类
/** * 金额小数转换成中文大写金额 * * @author Neil Han * */ private static final String UNIT[] = { "万", ...
- flask day01
目标:搭建好一个flask架构,并且可以运行起来,能够访问 ## 一丶配置环境 比较简单,只需要配一个flask pip3 install flask #也可以使用pip install flask ...
- SQL PLUS的语句执行Commit
oracle 中有个commit,是用来提交事务的.今天发现sql developer和sql plus的数据查询不一样. 如果我们对数据库进行增删改查,在提交sql语句之后,如果不点击commit, ...
- windows系统安装python3.6.3和python3.7.0
一.装备好从官网下载的python软件包(3.6.3和3.7.0) 二.先安装python3.6.3 1.运行python3.6.3文件 2.选择默认 3.下一步,等待安装 4.检查是否安装成功 ,安 ...
- Linux 小知识翻译 - 「小型移动式PC」
这次介绍下新闻上提到的「小型移动式PC」.(这个当时日本新闻上的内容) 最近,经常在日本的大卖场中看到一种小型的移动式PC.不仅是小巧方便携带,而且价格也便宜.而且,省电功能的加入,使电池能工作更长的 ...