题目链接:BZOJ - 1016

题目分析

最小生成树的两个性质:

同一个图的最小生成树,满足:

1)同一种权值的边的个数相等

2)用Kruscal按照从小到大,处理完某一种权值的所有边后,图的连通性相等

这样,先做一次Kruscal求出每种权值的边的条数,再按照权值从小到大,对每种边进行 DFS, 求出这种权值的边有几种选法。

最后根据乘法原理将各种边的选法数乘起来就可以了。

特别注意:在DFS中为了在向下DFS之后消除决策影响,恢复f[]数组之前的状态,在DFS中调用的Find()函数不能路径压缩。

代码

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <cstdio>
  6. #include <algorithm>
  7.  
  8. using namespace std;
  9.  
  10. const int MaxN = 100 + 5, MaxM = 1000 + 5, Mod = 31011;
  11.  
  12. int n, m, Top, Sum, Cnt;
  13. int f[MaxN], L[MaxM], R[MaxM], Num[MaxM];
  14.  
  15. typedef long long LL;
  16. LL Ans;
  17.  
  18. struct Edge
  19. {
  20. int u, v, w;
  21. } E[MaxM];
  22.  
  23. inline bool Cmp(Edge e1, Edge e2)
  24. {
  25. return e1.w < e2.w;
  26. }
  27.  
  28. inline int Find(int x, int o)
  29. {
  30. int i, j, k;
  31. j = x;
  32. while (j != f[j]) j = f[j];
  33. if (o == 1) return j;
  34. i = x;
  35. while (i != j)
  36. {
  37. k = i;
  38. i = f[i];
  39. f[k] = j;
  40. }
  41. return j;
  42. }
  43.  
  44. void DFS(int Type, int x, int y)
  45. {
  46. if (x == R[Type] + 1)
  47. {
  48. if (y == Num[Type]) ++Cnt;
  49. return;
  50. }
  51. int fx, fy;
  52. fx = Find(E[x].u, 1); fy = Find(E[x].v, 1);
  53. if (fx != fy)
  54. {
  55. f[fx] = fy;
  56. DFS(Type, x + 1, y + 1);
  57. f[fx] = fx;
  58. }
  59. DFS(Type, x + 1, y);
  60. }
  61.  
  62. int main()
  63. {
  64. scanf("%d%d", &n, &m);
  65. for (int i = 1; i <= m; ++i)
  66. scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w);
  67. sort(E + 1, E + m + 1, Cmp);
  68. Top = 0; Sum = 0;
  69. int fx, fy;
  70. for (int i = 1; i <= n; ++i) f[i] = i;
  71. for (int i = 1; i <= m; ++i)
  72. {
  73. if (i == 1 || E[i].w != E[i - 1].w) L[++Top] = i;
  74. R[Top] = i;
  75. fx = Find(E[i].u, 0); fy = Find(E[i].v, 0);
  76. if (fx != fy)
  77. {
  78. f[fx] = fy;
  79. ++Num[Top];
  80. ++Sum;
  81. }
  82. }
  83. if (Sum != n - 1)
  84. {
  85. printf("0\n");
  86. return 0;
  87. }
  88. for (int i = 1; i <= n; ++i) f[i] = i;
  89. Ans = 1;
  90. for (int i = 1; i <= Top; ++i)
  91. {
  92. if (Num[i] == 0) continue;
  93. Cnt = 0;
  94. DFS(i, L[i], 0);
  95. Ans = Ans * (LL)Cnt % Mod;
  96. for (int j = L[i]; j <= R[i]; ++j)
  97. {
  98. fx = Find(E[j].u, 0); fy = Find(E[j].v, 0);
  99. if (fx != fy) f[fx] = fy;
  100. }
  101. }
  102. printf("%d\n", (int)Ans);
  103. return 0;
  104. }

  

[BZOJ 1016] [JSOI2008] 最小生成树计数 【DFS】的更多相关文章

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

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

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

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

  3. bzoj 1016: [JSOI2008]最小生成树计数【dfs+克鲁斯卡尔】

    有一个性质就是组成最小生成树总边权值的若干边权总是相等的 这意味着按边权排序后在权值相同的一段区间内的边能被选入最小生成树的条数是固定的 所以先随便求一个最小生成树,把每段的入选边数记录下来 然后对于 ...

  4. BZOJ.1016.[JSOI2008]最小生成树计数(Matrix Tree定理 Kruskal)

    题目链接 最小生成树有两个性质: 1.在不同的MST中某种权值的边出现的次数是一定的. 2.在不同的MST中,连接完某种权值的边后,形成的连通块的状态是一样的. \(Solution1\) 由这两个性 ...

  5. bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...

  6. BZOJ 1016 [JSOI2008]最小生成树计数 ——Matrix-Tree定理

    考虑从小往大加边,然后把所有联通块的生成树个数计算出来. 然后把他们缩成一个点,继续添加下一组. 最后乘法原理即可. 写起来很恶心 #include <queue> #include &l ...

  7. 【BZOJ 1016】 1016: [JSOI2008]最小生成树计数 (DFS|矩阵树定理)

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

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

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

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

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

随机推荐

  1. [React] React Fundamentals: Build a JSX Live Compiler

    we want to have the ability to write JSX and see the output live in the browser. <!doctype html&g ...

  2. HDU2149-Good Luck in CET-4 Everybody!(博弈,打表找规律)

    Good Luck in CET-4 Everybody! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  3. Java IO流学习总结(转)

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  4. thinkphp中session跨域问题

    问题描述 <thinkphp实现短信验证注册>中,小编不止记录了短信验证码的实现方法,同时还记录了图片验证码的实现方法. 本地使用,一切正常:后端项目和前端项目都部署到服务器,一切正常:后 ...

  5. WTL 自绘 进度条Progressbar

    WTL 绘制的进度条,逻辑清晰明了,代码函数清晰易懂:基本思路就是 首先绘制 进度条背景图,然后根据动态进度不断重绘前景进度条,绘制操作在OnPaint函数里画.该类可以直接用于项目中. 使用示例: ...

  6. CSS背景颜色、背景图片、平铺、定位、固定

    CSS背景颜色设置 background-color:red;如设置背景颜色为红色: 背景颜色设置支持3种写法: 颜色名 16进制 rgb CSS背景图片颜色设置 background-image:u ...

  7. Powerdesigner中如何生成测试数据

    设计表完成以后,我们需要生成一些测试数据,可以直接更新到数据库中,下面我们就来试试: 第一步:建立需要的Profiles测试文件,[Model]--[Test Data Profiles],如图所示: ...

  8. bootstrap02导航菜单

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. Spring 注解回顾

    [copy] 参考资料 赵蒙

  10. js--小结②