题目大意:$n$个点和$m$条边(最多有$10$条边边权相同),求最小生成树个数

题解:对于所有最小生成树,每种边权的边数是一样的。于是就可以求出每种边权在最小生成树中的个数,枚举这种边的边集,求出对于这个边集可以的解(即没有一条边在同一联通块中),再把每种边的方案数乘起来即可。

卡点:

C++ Code:

  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4. const long long mod = 31011;
  5. struct Edge {
  6. int from, to, w;
  7. bool operator < (const Edge &a) const {return w < a.w;}
  8. } e[1010];
  9. int n, m;
  10. struct Set {
  11. int f[111];
  12. int find(int x) {return ((x == f[x]) ? x : (f[x] = find(f[x])));}
  13. bool operator = (const Set &a) {
  14. for (int i = 1; i <= n; i++) f[i] = a.f[i];
  15. }
  16. } s1, s2;
  17. long long ans = 1;
  18. int main() {
  19. scanf("%d%d", &n, &m);
  20. for (int i = 1; i <= m; i++) scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].w);
  21. sort(e + 1, e + m + 1);
  22. for (int i = 1; i <= n; i++) s1.f[i] = s2.f[i] = i;
  23. for (int i = 1; i <= m; i++) {
  24. int same = i, cnt = 0, res = 0;
  25. while (same < m && e[same].w == e[same + 1].w) same++;
  26. s1 = s2;
  27. for (int j = i; j <= same; j++) {
  28. int u = s1.find(e[j].from), v = s1.find(e[j].to);
  29. if (u != v) {
  30. s1.f[u] = v;
  31. cnt++;
  32. }
  33. }
  34. for (int j = 0; j < 1 << same - i + 1; j++) {
  35. bool flag = false;
  36. if (__builtin_popcount(j) == cnt) {
  37. flag = true;
  38. s1 = s2;
  39. for (int k = i; k <= same; k++) {
  40. if (j & 1 << k - i) {
  41. int u = s1.find(e[k].from), v = s1.find(e[k].to);
  42. if (u == v) {
  43. flag = false;
  44. break;
  45. } else s1.f[u] = v;
  46. }
  47. }
  48. }
  49. res += flag;
  50. }
  51. for (int j = i; j <= same; j++) {
  52. int u = s2.find(e[j].from), v = s2.find(e[j].to);
  53. if (u != v) s2.f[u] = v;
  54. }
  55. ans = (ans * res) % mod;
  56. }
  57. int tmp = s2.find(1);
  58. for (int i = 2; i <= n; i++) if (s2.find(i) != tmp) {
  59. puts("0");
  60. return 0;
  61. }
  62. printf("%d\n", ans);
  63. return 0;
  64. }

  

[洛谷P4208][JSOI2008]最小生成树计数的更多相关文章

  1. 洛谷P4208 [JSOI2008]最小生成树计数——题解

    题目传送 前置知识:对于同一个图的所有最小生成树,权值相等的边的数量相同. 可以简单证明一下: 我们可以从kruskal的过程考虑.这个算法把所有边按权值大小从小到大排序,然后按顺序看每条边,只要加上 ...

  2. Solution -「JSOI2008」「洛谷 P4208」最小生成树计数

    \(\mathcal{Description}\)   link.   给定带权简单无向图,求其最小生成树个数.   顶点数 \(n\le10^2\),边数 \(m\le10^3\),相同边权的边数不 ...

  3. 洛谷4208 JSOI2008最小生成树计数(矩阵树定理+高斯消元)

    qwq 这个题目真的是很好的一个题啊 qwq 其实一开始想这个题,肯定是无从下手. 首先,我们会发现,对于无向图的一个最小生成树来说,只有当存在一些边与内部的某些边权值相同的时候且能等效替代的时候,才 ...

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

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

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

    题意 给定一个 \(n\) 个点 \(m\) 条边的图,求最小生成树的个数. \(\texttt{Data Range:}1\leq n\leq 100,1\leq m\leq 10^4\) 题解 一 ...

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

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

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

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

  8. 1016: [JSOI2008]最小生成树计数

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

  9. 洛谷 P1596 [USACO10OCT]湖计数Lake Counting

    题目链接 https://www.luogu.org/problemnew/show/P1596 题目描述 Due to recent rains, water has pooled in vario ...

随机推荐

  1. Delphi方法重载

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  2. 商城项目:商品列表ajax加载,ajax加入购物车--五张表的联合查询

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ProductLists.a ...

  3. zabbix配置报警媒介-用户-动作-邮件脚本触发mailx邮件报警

    2018-09-16更新,新版本zabbix不需要使用脚本发送邮件,在zabbix web界面直接配置就可以 配置邮件参数,测试发送邮件 确认安装相关服务,centos7默认安装 [root@VM_1 ...

  4. POLYGON(动态规划)

    学校老师布置的一道动规的题目,要求下次上课前AC.周一一放学就回家写,调试了一会儿OK了.在这边记录一下解题的思路和过程,也作为第一篇随笔,就是随便之一写,您也就随便之一看.有问题望你指出,多多包涵. ...

  5. IDEA Java Web(Spring)项目从创建到打包(war)

    创建Maven管理的Java Web应用 创建新项目,"create new project",左侧类型选择"maven",右侧上方选择自己的SDK,点击&qu ...

  6. ISE中FPGA的实现流程

    一.ISE实现的步骤         在综合之后,我们开始启动FPGA在ISE中的实现过程,整个过程包括以下几个步骤:                 1.Translate              ...

  7. 20145202 《网络对抗技术》 PC平台逆向破解

    20145202 <网络对抗技术> PC平台逆向破解 准备工作 先将环境设置为:堆栈可执行.地址随机化关闭 参考http://git.oschina.net/wildlinux/NetSe ...

  8. Python正则反向引用

    str2 ="2018-10-29"c =re.sub(r"(\d{4})-(\d{2})-(\d{2})","\g<1>/\g<2 ...

  9. rails 中 preload、includes、Eager load、Joins 的区别

    Rails 提供了四种不同加载关联数据的方法.下面就来介绍一下. 一.Preload Preload 是以附加一条查询语句来加载关联数据的 User.preload(:posts).to_a # =& ...

  10. 「学习记录」《数值分析》第三章计算实习题(Python语言)

    第三题暂缺,之后补充. import matplotlib.pyplot as plt import numpy as np import scipy.optimize as so import sy ...