Wc2008 遊覽計畫 斯坦納樹

2021-09-11 16:05:53 字數 1579 閱讀 2726

斯坦納樹的問題模型是:有乙個圖,要求保留圖中最少的邊/最小的邊權和使得某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,則該方塊為乙個景點 否則表示控制該方塊至少需要的志願者...