又是图论里的一个可怕的数据结构。。
【斯坦纳树的定义】
给定个无向图和图上的一些点组成的点集,那么能使这些点集连通的该图的子树就是该图对于该点集的一颗斯坦纳树。
那么最小斯坦纳树就是所有斯坦纳树中边权值和最小的一颗。
其实就是最小生成树问题的一个衍伸,当这个点集包含图中所有的点的时候那么问题便转换为最小生成树。
【斯坦纳树的求法】
用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