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

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 6032  Solved: 2452
[Submit][Status][Discuss]

Description

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

Input

  第一行包含两个数,n和m,其中1<=n<=100; 1<=m<=1000; 表示该无向图的节点数和边数。每个节点用1~n的整
数编号。接下来的m行,每行包含两个整数:a, b, c,表示节点a, b之间的边的权值为c,其中1<=c<=1,000,000,0
00。数据保证不会出现自回边和重边。注意:具有相同权值的边不会超过10条。

Output

  输出不同的最小生成树有多少个。你只需要输出数量对31011的模就可以了。

Sample Input

4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1

Sample Output

8

分析:这道题还是比较坑的......首先我们要利用一条性质:一个图的所有的最小生成树的同一边权的边的数目是相等的,也就是说:我们如果把最小生成树上的边权排序,那么所有最小生成树的排列都是一样的。这个要怎么证明呢?为了简便起见,我们假设有2个不同的边权x1,x2,x1<x2,如果x1有2个,x2有2个,另一个最小生成树x1有3个,x2有1个,那么这是不可能的,因为第二个最小生成树的边权和已经比第一个的小了,如果第二个最小生成树x1有1个,x2有3个,这也不是最小生成树,以此类推,就能证明这个性质(可能不是完全正确的,但是明白这个结论就好了)。

知道这个结论就比较好处理了。我们接下来要做的就是枚举每个边权满足要求的边数,这里满足的要求是fa[x] != fa[y],也就是构成最小生成树的要求,因为有这个限制,所以不能用组合数,于是我们用dfs,看到了最后是不是达到了我们一开始求的那个最小生成树的边权的边的数目。也就是说:我们以第一个最小生成树为模板,后面的生成树的边权数与第一个相等的边的数目必须相等,同时检测是不是满足要求就可以了。

有一个坑点:这个图可能不能成为一棵树......

还有一个坑点:并查集不能用路径压缩,不然dfs不好还原.

还有一个要注意的地方:我们枚举完一个边权的边后,要把这些边全部连起来,为什么呢,因为这为以后判断下一个边权的边是否满足条件奠定基础.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int mod = 31011;int n, m, fa[1100],cnt,tot,l[1100],r[1100],sum[1100],ans = 1;struct node
{int a, b, c;
}e[1010];bool cmp(node a, node b)
{return a.c < b.c;
}int find1(int x)
{if (x == fa[x])return x;return find1(fa[x]);
}int dfs(int x,int y,int z)
{int res = 0;if (y == r[x] + 1){if (z == sum[x])return 1;return 0;}int fx = find1(e[y].a), fy = find1(e[y].b);if (fx != fy){fa[fx] = fy;res += dfs(x, y + 1, z + 1);res %= mod;fa[fx] = fx;}res += dfs(x, y + 1, z);res %= mod;return res;
}int main()
{scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)fa[i] = i;for (int i = 1; i <= m; i++)scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].c);sort(e + 1, e + 1 + m, cmp);for (int i = 1; i <= m; i++){if (i == 1)l[++cnt] = 1;elseif (e[i].c != e[i - 1].c){r[cnt] = i - 1;l[++cnt] = i;}int fx = find1(e[i].a), fy = find1(e[i].b);if (fx != fy){fa[fx] = fy;tot++;sum[cnt]++;}}r[cnt] = m;if (tot != n - 1){printf("0\n");return 0;}for (int i = 1; i <= n; i++)fa[i] = i;for (int i = 1; i <= cnt; i++){int tmp = dfs(i,l[i],0);ans = (ans * tmp) % mod;for (int j = l[i]; j <= r[i]; j++){int fx = find1(e[j].a), fy = find1(e[j].b);if (fx != fy)fa[fx] = fy;}}printf("%d\n", ans % mod);return 0;
}

转载于:https://www.cnblogs.com/zbtrs/p/7341547.html

bzoj1016 [JSOI2008]最小生成树计数相关推荐

  1. BZOJ1016 [JSOI2008]最小生成树计数

    题意:给定一张n<=100,m<=1000的无向图,另外同样权值的边不超过10条,求最小生成树的数目. 思路:首先我们将不同的权值从小到大分开考虑. 我们证明下面定理:一个无向图全部的最小 ...

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

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

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

    1016: [JSOI2008]最小生成树计数 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 5893  Solved: 2395 [Submit][ ...

  4. 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理

    蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...

  5. BZOJ1016:[JSOI2008]最小生成树计数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1016 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不 ...

  6. BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】

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

  7. [JSOI2008]最小生成树计数

    OJ题号: BZOJ1016 题目大意: 给定一个无向带权图,求最小生成树的个数. 思路: 先跑一遍最小生成树,统计相同权值的边出现的个数. 易证不同的最小生成树,它们不同的那一部分边的权值实际上是相 ...

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

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

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

    传送门 首先最小生成树有这么两个性质 1.不同的最小生成树中,每种权值的边出现的个数是确定的2.不同的生成树中,某一种权值的边连接完成后,形成的联通块状态是一样的 打个比方,以下图为例(图是网上的) ...

最新文章

  1. GfK公司将IT设备移至Equinix公司在法兰克福的数据中心
  2. 脏读,不可重复读,幻读
  3. gantt project 使用
  4. 创建mysql的表怎么显示00_Mysql sql_mode设置 timestamp default 0000-00-00 00:00:00 创建表失败处理...
  5. 明天14点直播间见!5位业内大咖带您解锁数据库内核技术与行业应用
  6. Extjs window组件 拖动统制
  7. 【报告分享】2019宠物消费生态大数据报告.pdf
  8. heartbeat双机热备配置(适用centos6\rhel6)
  9. Mac如何修改文件默认打开方式?
  10. QT ListView 记录
  11. (附源码)springboot超市仓库管理系统 毕业设计164555
  12. 浅谈代理服务器的作用
  13. 基于JavaEye-API实现的Gerry-聊天Dos版v1.0
  14. Circular-Circular 和 Circular-Linear Regression
  15. Visual Studio2012安装失败
  16. 向企业微信发送文字、图片的接口【亲测有效】
  17. (美化)WordPress网站添加自定义字体
  18. CCF-乘用车细分市场销量预测竞赛
  19. C# 动态 条件 组合_3D模型+平滑,在PPT中实现动态呈现
  20. WuThreat身份安全云-TVD每日漏洞情报-2023-01-17

热门文章

  1. 联想小新锐7000设置vt_小新Pro 14 2021正式发布,联想举行秋季新品发布会,10款新品齐亮相...
  2. c语言 中多一个分号,问什么C程序里总是提示缺少分号;,而明明有分号?
  3. windows与linux网络设置(host-only)
  4. Python+Opencv实现模板匹配
  5. Python函数式编程简介(三)匿名函数
  6. 【Transformer】Augmented Shortcuts for Vision Transformers
  7. 【python 11】super()
  8. 三行情书代码_用三行代码优化您的交易策略
  9. 大学生每个月1500元的生活费,够吗?
  10. 导演李大为婚礼全过程(二)