又是圖論裡的乙個可怕的資料結構。。
【斯坦納樹的定義】
給定個無向圖和圖上的一些點組成的點集,那麼能使這些點集連通的該圖的子樹就是該圖對於該點集的一顆斯坦納樹。
那麼最小斯坦納樹就是所有斯坦納樹中邊權值和最小的一顆。
其實就是最小生成樹問題的乙個衍伸,當這個點集包含圖中所有的點的時候那麼問題便轉換為最小生成樹。
【斯坦納樹的求法】
用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。
具體**如下。
將演算法封裝至結構體只是個人習慣,有需要的話可以拆開來寫。
#includeusing namespace std;
struct edge
};struct steinertree
}} }
void buildtree()//求最小斯坦納樹 }}
if(dp[i][j]!=-1)
}spfa(j);
} }}s;
模板 斯坦納樹
include int main 斯坦納樹 time limit 1 sec memory limit 128 mb description 現在有乙個n m的矩陣,某些元素為0,剩下的元素大於0.現在你要選擇一些元素,使得任意兩個為0的元素都能夠通過選中的元素四連通.注意,若想達到要求,所有的0自...
斯坦納樹模板
出自lxw部落格 給出n個點,然後給出m條雙向邊,邊有邊權。再給出乙個大小為k的點集,求使得點集聯通的最小花費。時間複雜度o n 3 k ce 2 k 其中c為spfa常數。include define rep i,a,b for int i a i b i using namespace std ...
斯坦納樹小結
做題時偶然遇到就學了一下,並不是什麼很難的高科技。最小斯坦納樹和最小生成樹類似,不過為了達到最小開銷,最小斯坦納樹允許加一些額外點。例題 有一張圖,有 k kk 個關鍵點,選出一些邊,使這 k kk 個點形成連通塊,求邊權和的最小值。演算法流程 不難發現,這樣的連通塊一定是棵樹,成環的話隨便去掉環上...