【模板】斯坦纳树

斯坦纳树是图论中的一个重要概念,它是连接特定点集的图的子树,使得这些点连通且边权和最小。当点集包含所有图中的点时,问题转化为最小生成树。通过动态规划可以求解斯坦纳树,涉及的状态转移包括两棵树的拼接和边的松弛操作,可以用SPFA实现。
摘要由CSDN通过智能技术生成

又是图论里的一个可怕的数据结构。。

【斯坦纳树的定义】

给定个无向图和图上的一些点组成的点集,那么能使这些点集连通的该图的子树就是该图对于该点集的一颗斯坦纳树。

那么最小斯坦纳树就是所有斯坦纳树中边权值和最小的一颗。

其实就是最小生成树问题的一个衍伸,当这个点集包含图中所有的点的时候那么问题便转换为最小生成树。

【斯坦纳树的求法】

用dp来求就行了。具体的dp写法也是参考了这个博客才知道怎么写的。

设dp[i][bitmask]为以i为根且点集中bitmask代表的点在这颗树上时的最小边权值和。

首先要保证一个原则,当i为点集上的点的时候,bitmask里必须要有i,如果有没满足这个条件的转移要将i这个点强制加进bitmask中。

于是有两种状态转移:

1. dp[i][sub1]+dp[i][sub2],其中sub1和sub2为bitmask的两个子集,并且sub1+sub2=bitmask。

这种状态转移其实就是两颗以i为根的树拼接起来。

2. dp[j][bitmask]+e[i][j],其中j为与i相邻的点,e[i][j]即为两点的连边的权值。

这一步操作其实就是图中的边的松弛操作,用SPFA解决就行了。

这种状态转移其实就是在以i为根的这颗树上拼上点j。


具体代码如下。

将算法封装至结构体只是个人习惯,有需要的话可以拆开来写。

#include<bits/stdc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值