斯坦納樹的問題模型是:有乙個圖,要求保留圖中最少的邊/最小的邊權和使得某k個點相互連通。最小生成樹是斯坦納樹的一種特殊情況。
我們用f[i]][j][s]表示方格中i,j位置與各個景點之間的聯通情況。
如果景點數為3時,111表示全部聯通, 101表示第二個景點沒有聯通。。。
當然第x個景點的 f[i][j][(1《狀態怎麼轉移?
有兩種情況
1.某個狀態的子狀態(11011->10001)。
2.相鄰的位置轉移過來的。
子狀態的話需要知道乙個枚舉子狀態的技巧:
for
(int s = st&
(st-1)
; s; s = st&
(s-1
))
相鄰的狀態轉移就要用spfa了。
#pragma gcc optimize(2)
#include
using namespace std;
const
int maxn =
1<<12;
int case =1;
int n, m, cc[12]
[12], f[12]
[12][maxn]
, vis[12]
[12], res[12]
[12];
int dr[4]
[2]=
,,,}
;queueint,
int>
>q;
struct nodepre[12]
[12][maxn]
;void
dfs(
int x,
int y,
int s)
void
spfa
(int s);if
(!vis[nx]
[ny]
) q.
push
(make_pair
(nx, ny)
), vis[nx]
[ny]=1
;}}}
}void
solve()
}}int mx =
1
int st =
0; st < mx; st++);
}}if(f[i]
[j][st]
<
0x3f3f
) q.
push
(make_pair
(i, j)
), vis[i]
[j]=1;
}}spfa
(st);}
printf
("%d\n"
, f[sx]
[sy][(
1<])
;dfs
(sx, sy,(1
<);
for(
int i =
1; i <= n; i++
)printf
("\n");
}return;}
intmain()
return0;
}
P4294 WC2008 遊覽計畫 斯坦納樹
題目鏈結 差不多是斯坦納樹裸題,不過邊權化成了點權,這樣在合併兩棵子樹時需要去掉根結點的權值,防止重複。題目還要求輸出解,只要在轉移時記錄下路徑,然後dfs一遍就好了。1 include2 using namespace std 3 typedef long long ll 4 const int ...
WC2008 遊覽計畫 狀壓dp
題面太鬼畜不粘了。題意就是給一張n m的網格圖,每個點有點權,有k個關鍵點,讓你把這k個關鍵點連成乙個聯通快的最小代價。題解 這題nmk都非常小,解法肯定是狀壓,比較一般的解法插頭dp,但不太好寫。但其實這道題是裸的斯坦納樹模型。斯坦納樹是最小生成樹的變形,在一般情況下是np問題,但在k規模較少時可...
WC2008遊覽計畫(BZOJ2595)
傳送門 time limit 10 sec memory limit 256 mbsec special judge submit status 第一行有兩個整數,n和 m,描述方塊的數目。接下來 n行,每行有 m 個非負整數,如果該整數為 0,則該方塊為乙個景點 否則表示控制該方塊至少需要的志願者...