做題時偶然遇到就學了一下,並不是什麼很難的高科技。
最小斯坦納樹和最小生成樹類似,不過為了達到最小開銷,最小斯坦納樹允許加一些額外點。
例題:有一張圖,有 k
kk 個關鍵點,選出一些邊,使這 k
kk 個點形成連通塊,求邊權和的最小值。
演算法流程:
不難發現,這樣的連通塊一定是棵樹,成環的話隨便去掉環上一條邊都可以使答案更小。
考慮狀壓dp,設 fi,
sf_
fi,s
表示以 i
ii 為根的子樹,子樹內包含 s
ss 這些關鍵點,其中 s
ss 在二進位制下第 j
jj 位為 1
11 表示包含第 j
jj 個關鍵點。
轉移分兩類:
轉移的順序也很好確定,即從小到大列舉 s
ss,每次先進行第一類轉移,然後再進行第二類轉移。
仔細觀察第二類轉移,本質上是if(f[v][s]+w[v][u]然後就沒了,十分簡單。
**如下:
#include高階題:有一張圖,有一些關鍵點,每個關鍵點有乙個頻率,你要選出一些邊,使相同頻率的關鍵點成為連通塊。#include
#include
using
namespace std;
#define maxn 110
int n,m,k;
struct edgee[
2010];
int first[maxn]
,len=0;
void
buildroad
(int x,
int y,
int z)
;first[x]
=len;
}int f[maxn][(
1<<10)
+1];
int q[maxn]
,st,ed;
bool v[maxn]
;int
main()
memset
(f,63
,sizeof
(f))
;for
(int i=
1,x;i<=k;i++
)scanf
("%d"
,&x)
,f[x][1
<<
(i-1)]
=0;for
(int s=
1;s<(1
<;s++)}
}}int ans=
2e9;
for(
int i=
1;i<=n;i++
) ans=
min(ans,f[i][(
1<])
;printf
("%d"
,ans)
;}
題解問題不同在於,兩兩連通塊之間可能共用一些邊,從而使開銷更小。
假如有兩個連通塊共用了一些邊,那麼他們的斯坦納樹就是聯通的,並且依然不會出現環,也就是成為了一棵更大的斯坦納樹。
於是可以設 g[s
]g[s]
g[s]
表示 s
ss 內的關鍵點都在一棵斯坦納樹內的最小開銷,可以先將所有關鍵點跑一次斯坦納樹,這樣就可以得到 ggg。
然後再dp一下,g[s
]g[s]
g[s]
的定義就變成了 s
ss 內的關鍵點形成斯坦納森林的最小開銷。g[2
k−1]
g[2^k-1]
g[2k−1
] 就是答案。
**如下:
#include
#include
#include
#include
using
namespace std;
#define maxn 1010
int n,m,k;
struct edgee[
6010];
int first[maxn]
,len=0;
void
buildroad
(int x,
int y,
int z)
;first[x]
=len;
}vector<
int> key[11]
;int f[maxn][(
1<<10)
+1];
int q[maxn]
,st,ed;
bool v[maxn]
;int
steiner()
}}}}
int g[(1
<<10)
+1];
intmain()
memset
(f,63
,sizeof
(f))
;for
(int i=
1,x,y;i<=k;i++
)steiner()
;for
(int i=
0;i<(1
<;i++
)for
(int i=
0;i<(1
<;i++
)for
(int j=i;j;j=
(j-1
)&i)
g[i]
=min
(g[i]
,g[j]
+g[i^j]);
printf
("%d"
,g[(
1<])
;}
模板 斯坦納樹
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 ...