JSOI 2008 最小生成树计数
JSOI 2008 最小生成树计数
今天的题目终于良心一点辣
一个套路+模版题。
考虑昨天讲的那几个结论,我们有当我们只保留最小生成树中权值不超过 $ k $ 的边的时候形成的联通块是一定的。
我们可以先拿 kruskal 跑一棵最小生成树,然后我们可以从小到大枚举边权,把所有除开枚举到的边权的边全部加入并且缩点。现在我们就在这个缩点后的点集进行生成树计数就好了。答案就是每种边权算出答案的积。
因为我们知道,连入 $ k $ 边权的边后对于 $ 1 $ 到 $ k - 1 $ 的边加入后的最小生成树的影响是固定的,加入后得到的联通块必然一样。所以加入每个权值实际上是独立的!
但是这题很sb的一点在于,它同种边权数量不超过 10 可以直接暴力。如果是100就得矩阵树定理了。(但是这题模数非质数很烦)
#include "iostream"
#include "algorithm"
#include "cstring"
#include "cstdio"
#include "vector"
using namespace std;
#define P 31011
#define MAXN 106
int n , m;
int power( int a , int x ) {
int cur = a % P , ans = 1;
while( x ) {
if( x & 1 ) ans = ans * cur % P;
cur = cur * cur % P , x >>= 1;
}
return ans;
}
struct ed {
int u , v , w;
} E[1006] , T[MAXN] ; int cn = 0;
bool cmp( ed a , ed b ) { return a.w < b.w; }
int fa[MAXN];
vector<int> w;
int find( int x ) { return x == fa[x] ? x : fa[x] = find( fa[x] ); }
int to[MAXN];
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
int main() {
cin >> n >> m;
for( int i = 1 ; i <= m ; ++ i )
scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);
sort( E + 1 , E + 1 + m , cmp );
for( int i = 1 ; i <= n ; ++ i ) fa[i] = i;
for( int i = 1 ; i <= m ; ++ i ) {
int u = find( E[i].u ) , v = find( E[i].v ) ;
if( u == v ) continue;
fa[u] = v;
T[++ cn] = E[i];
w.push_back( E[i].w );
}
w.erase( unique( w.begin() , w.end() ) , w.end() );
vector<pii> eds;
int ans = 1;
for( int a : w ) {
int cur = 0;
int sz = 0;
for( int i = 1 ; i <= n ; ++ i ) fa[i] = i;
for( int i = 1 ; i <= cn ; ++ i ) if( T[i].w != a )
fa[find( T[i].u )] = find( T[i].v );
for( int i = 1 ; i <= n ; ++ i ) if( find( i ) == i ) to[i] = ++ sz;
eds.clear();
for( int i = 1 ; i <= m ; ++ i ) {
int u = find( E[i].u ) , v = find( E[i].v );
if( u == v || E[i].w != a ) continue;
eds.emplace_back( mp( to[u] , to[v] ) );
}
int S = eds.size();
for( int i = 0 ; i < ( 1 << S ) ; ++ i ) {
int ok = 0;
for( int j = 1 ; j <= sz ; ++ j ) fa[j] = j;
for( int j = 0 ; j < S ; ++ j ) if( i & ( 1 << j ) ) {
if( find( eds[j].fi ) != find( eds[j].se ) )
fa[find(eds[j].fi)] = find(eds[j].se);
else { ok = 1; break; }
}
for( int j = 1 ; j <= sz ; ++ j ) if( find( j ) != find( 1 ) ) { ok = 1 ; break; }
if( !ok ) ++ cur;
}
ans = ans * cur % P;
}
cout << ans << endl;
}
JSOI 2008 最小生成树计数的更多相关文章
- BZOJ 1016 JSOI 2008 最小生成树计数 Kruskal+搜索
题目大意:给出一些边,求出一共能形成多少个最小生成树. 思路:最小生成树有非常多定理啊,我也不是非常明确.这里仅仅简单讲讲做法.关于定各种定理请看这里:http://blog.csdn.net/wyf ...
- 最小生成树计数 bzoj 1016
最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...
- 【bzoj1016】 JSOI2008—最小生成树计数
http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...
- [BZOJ]1016 JSOI2008 最小生成树计数
最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...
- bzoj1016 [JSOI2008]最小生成树计数
1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3517 Solved: 1396[Submit][St ...
- 【BZOJ】【1016】【JSOI2008】最小生成树计数
Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
- BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1016 给出一张图,其中具有相同权值的边的数目不超过10,求最小生成树的个数. 分析 生成树的计 ...
- BZOJ 1016: [JSOI2008]最小生成树计数( kruskal + dfs )
不同最小生成树中权值相同的边数量是一定的, 而且他们对连通性的贡献是一样的.对权值相同的边放在一起(至多10), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
随机推荐
- tomcat内存马原理解析及实现
内存马 简介 Webshell内存马,是在内存中写入恶意后门和木马并执行,达到远程控制Web服务器的一类内存马,其瞄准了企业的对外窗口:网站.应用.但传统的Webshell都是基于文件类型的,黑客 ...
- [no code][scrum meeting] Alpha 5
项目 内容 会议时间 2020-04-10 会议主题 后端技术讨论 会议时长 30min 参会人员 全体成员 $( "#cnblogs_post_body" ).catalog() ...
- Photoshop cc 绿色版 最新版 下载
Photoshop cc 绿色版 下载 Photoshop cc 绿色版 最新版下载百度网盘下载 Photoshop 下载提取码: dh6z 作为一个程序员, 不懂点基本的作图都不配"新时代 ...
- 链式A+B 牛客网 程序员面试金典 C++ Python
链式A+B 牛客网 程序员面试金典 C++ Python 题目描述 有两个用链表表示的整数,每个结点包含一个数位.这些数位是反向存放的,也就是个位排在链表的首部.编写函数对这两个整数求和,并用链表形式 ...
- AtCoder Beginner Contest 213 F题 题解
F - Common Prefixes 该题也是囤了好久的题目了,看题目公共前缀,再扫一眼题目,嗯求每个后缀与其他后缀的公共前缀的和,那不就是后缀数组吗?对于这类问题后缀数组可是相当在行的. 我们用后 ...
- POJ 2446 Chessboard(二分图最大匹配)
题意: M*N的棋盘,规定其中有K个格子不能放任何东西.(即不能被覆盖) 每一张牌的形状都是1*2,问这个棋盘能否被牌完全覆盖(K个格子除外) 思路: M.N很小,把每一个可以覆盖的格子都离散成一个个 ...
- Envoy实现.NET架构的网关(五)集成Redis实现限流
什么是限流 限流即限制并发量,限制某一段时间只有指定数量的请求进入后台服务器,遇到流量高峰期或者流量突增时,把流量速率限制在系统所能接受的合理范围之内,不至于让系统被高流量击垮.而Envoy可以通过e ...
- python解释器的下载与安装
python解释器 1. 什么是python解释器 用一种能让电脑听的懂得语言,使得电脑可以听从人们的指令去进行工作(翻译官) Python解释器本身也是个程序, 它是解释执行Python代码的,所以 ...
- 部署自己的gitlab服务器
一.安装依赖环境,下载gitlab的rpm包,并且安装 yum install curl policycoreutils-python openssh-server postfix wget -ywg ...
- HTML 简单介绍
1.什么是HTML > HTML是用来描述网页的一种语言 > HTML指的是超文本标记语言(Hyper Text Markup Language) > 标记语言是一套标记标签(mar ...