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), 暴搜他们有多少种方案, 然后乘法原理. ----------------------- ...
随机推荐
- SLAM名词介绍
gauge freedom:测量自由度 degrees-of-freedom(DoF) 自由度 wide-baseline matches:宽基线匹配 宽基线匹配:从描绘同一场景的两个或多个图像中建立 ...
- [对对子队]会议记录5.15(Scrum Meeting2)
今天已完成的工作 吴昭邦 工作内容:衔接循环指令系统,搭建第4关 相关issue:实现循环组件 相关签入:feat: 将模型加入第四关 第四关可以顺利通过 何瑞 工作内容:衔接循环指令 ...
- 【二食堂】Alpha - 事后分析
事后分析 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Alpha阶段要解决的问题是:根据用户标注的信息完成知识图谱的生成渲染.要解决的问题定义得比较 ...
- CodeForces-1076E Vasya and a Tree
CodeForces - 1076E Problem Description: Vasya has a tree consisting of n vertices with root in verte ...
- TensorFlow从入门到入坑(2)
TensorFlow学习(2) 一.jupyter notebook的安装和使用 1. 什么是jupyter notebook jupyter notebook(http://jupyter.org/ ...
- configure: error: invalid variable name: `'
今天在交叉编译一个编解码库的时候,出现一个莫名其妙的报错,一直找不到原因,后来无意中删除了一个空格,才发现就是这个空格造成的错误. ./configure --host=arm-linux LDFLA ...
- 二进制小数 牛客网 程序员面试金典 C++ Python
二进制小数 牛客网 程序员面试金典 题目描述 有一个介于0和1之间的实数,类型为double,返回它的二进制表示.如果该数字无法精确地用32位以内的二进制表示,返回"Error". ...
- 【网络好文】---MySQL为Null导致的四大坑
正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如所示: select version(); -- 版本为 8.0.22 "兵马未动粮草先行",看完了相关的配置之 ...
- Linux 兴趣小组2016免试题 第四关揭秘
Linux 兴趣小组2016免试题 点这里 首先贴出第四关链接Linux 兴趣小组2016免试题 第四关 第四关: 进入网址我们看到的是4张扑克牌K,这是什么意思? 要我斗地主?好了,还是乖乖的先查看 ...
- kubernetes常见日志采集问题和解决方案分析
传统日志与kubernetes日志对比 传统服务 目录固定 重启不会丢失 不用关注标准与错误日志输出 容器服务 节点不固定 重启服务会漂移 需要关注标准与错误日志输出 日志文件重启会丢失 日志目录不固 ...