給定乙個包含 \(n\) 個結點和 \(m\) 條帶權邊的無向連通圖 \(g=(v,e)\)。
再給定包含 \(k\) 個結點的點集 \(s\),選出 \(g\) 的子圖 \(g'=(v',e')\) 使得:
\(s\subseteq v'\)
\(g′\) 為連通圖;
\(e′\) 中所有邊的權值和最小。
你只需要求出 \(e′\)中所有邊的權值和。
\(dp[i][s]\) 表示 以 i 為根的一棵樹,包含集合 s 中所有點的最小代價 \(i\) 號點不一定在 \(s\) 中
\(w[i][j] + dp[j][s] -> dp[i][s]\)
\(dp[i][t] + dp[i][s-t] -> dp[i][s]\quad(t \subseteq s)\)
第二類轉移可以用列舉子集來轉移,第一類轉移是乙個三角不等式,可以用\(spfa\)或者\(dijkstra\)
第一類轉移複雜度為\(o(m\log m \times 2^k)\)
第二類轉移複雜度為\(o(n\times 3^n)\) ,子集列舉的時間複雜度可以用二項式定理求出
**:
const int n = 100 + 5;
const int m = 1010;
int n, m, k, x, y, z, tot;
int head[n], ver[m], nxt[m], edge[m], dp[n][4200];
int p[n], vis[n];
priority_queue> q;
void add(int x, int y, int z)
void dijkstra(int s)}}
}int main()
memset(dp, 0x3f, sizeof dp);
for(int i=1;i<=k;i++)
for(int s = 1; s < (1 << k); s++)
if(dp[i][s]!=inf) q.push(make_pair(-dp[i][s], i));
}dijkstra(s);
}printf("%d\n", dp[p[1]][(1《給出一張圖,求讓 \(4\) 對點相互可以到達的最小邊權值。僅要求一對之間,一對與另外一對可到達也可不到達。
題目鏈結
先對於8個點求出最小斯坦納樹,然後求出\(res[s] = \min_ dp[i][s]\) ,表示點集為 \(s\) 的最小斯坦納樹路徑和。有些 \(s\) 是不合法的,因為它不能完整的包含4對點中的某一對(如果包含某個點,則必須包含該點的配對點,否則就不包含)。去除這些不合法的集合 \(s\), 在合法的集合之間進行狀壓\(dp\)轉移即可。
const int n = 30 + 5;
const int m = 2000;
int n, m, k, tot, cnt;
int head[n], ver[m], nxt[m], edge[m], dp[n][(1<<8)], res[1<<8];
int p[n], vis[n];
mapmp;
priority_queue> q;
void add(int x, int y, int z)
int getid(string str)
void dijkstra(int s)}}
}bool check(int s)
return true;
}int main()
for(int i=1;i<=m;i++)
for(int i=1;i<=4;i++)
k = 8;
memset(dp, 0x3f, sizeof dp);
for(int i=1;i<=k;i++)
for(int s = 1; s < (1 << k); s++)
if(dp[i][s]!=inf) q.push(make_pair(-dp[i][s], i));
}dijkstra(s);
}//以上為斯坦納樹模板
memset(res, 0x3f, sizeof res);
for(int s = 1; s < (1<}
for(int s = 1; s < (1 << k); s++)
}printf("%d\n", res[(1
}
最小斯坦納樹
給定乙個包含 n 個點和 m 條邊的無向聯通圖 g v,e 再給定包含 k 個結點的點集 s 選出 g 的子圖 g v e 使得 s subseteq v g 為連通圖 e 中所有邊的邊權和最小。由於要求邊權和最小,我們最後得到的一定是一棵樹,我們稱之為最小斯坦納樹。一般情況下 s 的元素個數都非常...
最小斯坦納樹 學習筆記
斯坦納樹問題是組合優化問題,與最小生成樹相似,是最短網路的一種。最小生成樹是在給定的點集和邊中尋求最短網路使所有點連通。而最小斯坦納樹允許在給定點外增加額外的點,使生成的最短網路開銷最小。可以這麼理解 乙個圖的生成樹是構造一棵樹把所有點給聯通,而斯坦納樹則是構造一棵樹把給定的幾個點聯通。如同生成樹有...
模板 斯坦納樹
include int main 斯坦納樹 time limit 1 sec memory limit 128 mb description 現在有乙個n m的矩陣,某些元素為0,剩下的元素大於0.現在你要選擇一些元素,使得任意兩個為0的元素都能夠通過選中的元素四連通.注意,若想達到要求,所有的0自...