JSOI 2008 最小生成树计数

今天的题目终于良心一点辣

一个套路+模版题。

考虑昨天讲的那几个结论,我们有当我们只保留最小生成树中权值不超过 $ k $ 的边的时候形成的联通块是一定的。

我们可以先拿 kruskal 跑一棵最小生成树,然后我们可以从小到大枚举边权,把所有除开枚举到的边权的边全部加入并且缩点。现在我们就在这个缩点后的点集进行生成树计数就好了。答案就是每种边权算出答案的积。

因为我们知道,连入 $ k $ 边权的边后对于 $ 1 $ 到 $ k - 1 $ 的边加入后的最小生成树的影响是固定的,加入后得到的联通块必然一样。所以加入每个权值实际上是独立的!

但是这题很sb的一点在于,它同种边权数量不超过 10 可以直接暴力。如果是100就得矩阵树定理了。(但是这题模数非质数很烦)

  1. #include "iostream"
  2. #include "algorithm"
  3. #include "cstring"
  4. #include "cstdio"
  5. #include "vector"
  6. using namespace std;
  7. #define P 31011
  8. #define MAXN 106
  9. int n , m;
  10. int power( int a , int x ) {
  11. int cur = a % P , ans = 1;
  12. while( x ) {
  13. if( x & 1 ) ans = ans * cur % P;
  14. cur = cur * cur % P , x >>= 1;
  15. }
  16. return ans;
  17. }
  18. struct ed {
  19. int u , v , w;
  20. } E[1006] , T[MAXN] ; int cn = 0;
  21. bool cmp( ed a , ed b ) { return a.w < b.w; }
  22. int fa[MAXN];
  23. vector<int> w;
  24. int find( int x ) { return x == fa[x] ? x : fa[x] = find( fa[x] ); }
  25. int to[MAXN];
  26. #define pii pair<int,int>
  27. #define fi first
  28. #define se second
  29. #define mp make_pair
  30. int main() {
  31. cin >> n >> m;
  32. for( int i = 1 ; i <= m ; ++ i )
  33. scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);
  34. sort( E + 1 , E + 1 + m , cmp );
  35. for( int i = 1 ; i <= n ; ++ i ) fa[i] = i;
  36. for( int i = 1 ; i <= m ; ++ i ) {
  37. int u = find( E[i].u ) , v = find( E[i].v ) ;
  38. if( u == v ) continue;
  39. fa[u] = v;
  40. T[++ cn] = E[i];
  41. w.push_back( E[i].w );
  42. }
  43. w.erase( unique( w.begin() , w.end() ) , w.end() );
  44. vector<pii> eds;
  45. int ans = 1;
  46. for( int a : w ) {
  47. int cur = 0;
  48. int sz = 0;
  49. for( int i = 1 ; i <= n ; ++ i ) fa[i] = i;
  50. for( int i = 1 ; i <= cn ; ++ i ) if( T[i].w != a )
  51. fa[find( T[i].u )] = find( T[i].v );
  52. for( int i = 1 ; i <= n ; ++ i ) if( find( i ) == i ) to[i] = ++ sz;
  53. eds.clear();
  54. for( int i = 1 ; i <= m ; ++ i ) {
  55. int u = find( E[i].u ) , v = find( E[i].v );
  56. if( u == v || E[i].w != a ) continue;
  57. eds.emplace_back( mp( to[u] , to[v] ) );
  58. }
  59. int S = eds.size();
  60. for( int i = 0 ; i < ( 1 << S ) ; ++ i ) {
  61. int ok = 0;
  62. for( int j = 1 ; j <= sz ; ++ j ) fa[j] = j;
  63. for( int j = 0 ; j < S ; ++ j ) if( i & ( 1 << j ) ) {
  64. if( find( eds[j].fi ) != find( eds[j].se ) )
  65. fa[find(eds[j].fi)] = find(eds[j].se);
  66. else { ok = 1; break; }
  67. }
  68. for( int j = 1 ; j <= sz ; ++ j ) if( find( j ) != find( 1 ) ) { ok = 1 ; break; }
  69. if( !ok ) ++ cur;
  70. }
  71. ans = ans * cur % P;
  72. }
  73. cout << ans << endl;
  74. }

JSOI 2008 最小生成树计数的更多相关文章

  1. BZOJ 1016 JSOI 2008 最小生成树计数 Kruskal+搜索

    题目大意:给出一些边,求出一共能形成多少个最小生成树. 思路:最小生成树有非常多定理啊,我也不是非常明确.这里仅仅简单讲讲做法.关于定各种定理请看这里:http://blog.csdn.net/wyf ...

  2. 最小生成树计数 bzoj 1016

    最小生成树计数 (1s 128M) award [问题描述] 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一 ...

  3. 【bzoj1016】 JSOI2008—最小生成树计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1016 (题目链接) 题意 求图的最小生成树计数. Solution %了下题解,发现要写矩阵树,15 ...

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

    最小生成树计数 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同 ...

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

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

  6. 【BZOJ】【1016】【JSOI2008】最小生成树计数

    Kruskal/并查集+枚举 唉我还是too naive,orz Hzwer 一开始我是想:最小生成树删掉一条边,再加上一条边仍是最小生成树,那么这两条边权值必须相等,但我也可以去掉两条权值为1和3的 ...

  7. 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集

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

  8. BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1016 给出一张图,其中具有相同权值的边的数目不超过10,求最小生成树的个数. 分析 生成树的计 ...

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

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

随机推荐

  1. python常用功能

    1. 获取昨天日期 引入datetime模块 import datetime def getYesterday(): today = datetime.date.today() #返回当前本地日期 # ...

  2. 【UE4】 补丁Patch 与 DLC

    概述 UE4 中主要使用 Project Launcher 来进行补丁和DLC的制作 补丁与 DLC 都需要基于某个版本而制作 补丁 与 DLC 最后以 Pak 形式表现, 补丁的 pak 可以重命名 ...

  3. SpringCloud微服务实战——搭建企业级开发框架(六):使用knife4j集成Swagger2接口文档

    knife4j是为集成Swagger生成api文档的增强解决方案,前后端Java代码以及前端Ui模块进行分离,在微服务架构下使用更加灵活, 提供专注于Swagger的增强解决方案,不同于只是改善增强前 ...

  4. spring cache整合redis

    在项目中,我们经常需要将一些常用的数据使用缓存起来,避免频繁的查询数据库造成效率低下.spring 为我们提供了一套基于注解的缓存实现,方便我们实际的开发.我们可以扩展spring的cache接口以达 ...

  5. CPU使用率和平均负载

    转载: https://mp.weixin.qq.com/s?__biz=MzU4NzU0MDIzOQ==&mid=2247487782&idx=3&sn=3f04bb053d ...

  6. Linux上Qt旋转显示

    对于嵌入式设备来说用于显示的LCD总是千奇百怪,比如说明明是一个竖屏,但是客户却要当横屏使用,也就是意味着我们需要将整个屏幕上显示的内容旋转90度或者270度. 这个操作对于Android系统来说相当 ...

  7. 如何抓取直播源及视频URL地址-疯狂URL(教程)

    直播源介绍 首先,我们来快速了解一下什么是直播源,所谓的直播源,其实就说推流地址,推流地址可能你也不知道是什么,那么我再简单说一下,推流地址就是,当某个直播开播的时候,需要将自己的直播状态实时的展示给 ...

  8. Linux 安装nacos

    1.已有mysql环境 2.解压文件 #tar -zxvf package/nacos-server-2.0.1.tar.gz 3.创建数据库nacos_config(confnacos-mysql. ...

  9. Centos7+Postfix+Dovecot实现内网邮件收发

    1. 前期准备: 主机:CentOS release 7.6.1810 (Core)     #安装时选择邮件服务器 IP:192.168.71.108   #示例 本地yum源 #因为是内网,所以建 ...

  10. js 事件流和事件冒泡阻止

    js 事件流和事件冒泡阻止 事件流 当浏览器发展到第四代的时候(IE4与Netscape4)浏览器开发团队遇到一个有意思的的问题: 页面的哪一部分会拥有某个特定的事件? 比如在纸上画上一组同心圆,如果 ...