【图论】最小生成树计数【理解+学习】

描述

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

输入
 第一行包含两个数,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条。

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

样例输入 [复制]
4 6
1 2 1
1 3 1
1 4 1
2 3 2
2 4 1
3 4 1
样例输出 [复制]
8

//

用样例来理解最小生成树计数,发现限制很多

1.对于不同的最小生成树,边权总和是相等的,所以每一种边权的边的数量必须是不变的
2.既然有上述条件,可以对相同边权的边枚举看是否满足要求(相同权值的边的数目不超过10,赤裸裸的状压啊),(枚举的过程,相当于把不同的几个点连接到已经产生的最小的集合中,成为新的集合
2.1 如果顺着推下去,那么不同的连接情况是否会对后面的边的连接情况产生影响?
是不会的。 如果会有影响,说明有部分点没有连接到当前最小的集合,但当前是最优解,必须连接完所有可能连接的点。所以边虽然不一样,但最后加入最优解集合的点一定是完全相同的

2.2 枚举情况要确定总数。任一权值的边的数量在最小生成树中都是不变的,所以先做一遍最小生成树,维护当前权值边的数量来作为约束条件即可(从另一个的角度,相当于框定一个大的范围来优化时间)
2.3 注意当前边不能成环

(代码学习了某不知姓名的大佬的写法https://blog.csdn.net/wyfcyx_forever/article/details/40182739)
(这个代码最坏情况 1e7)

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e2+10,mod=31011;
struct edge{
   
	int u,v,s;
	inline void read(){
   
		scanf("%d%d%d",&u,&v,&s);
	}
	bool operator <(const edge &t) const{
   
		return s<t.s;
	}
}e[1005];
map<int,int> M;
int n,m; 
int fa[maxn],bet[maxn];
inline int find(int u){
   
	int again
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值