WC2008 遊覽計畫 狀壓dp

2022-07-13 20:27:14 字數 1449 閱讀 8321

題面太鬼畜不粘了。

題意就是給一張n*m的網格圖,每個點有點權,有k個關鍵點,讓你把這k個關鍵點連成乙個聯通快的最小代價。

題解

這題nmk都非常小,解法肯定是狀壓,比較一般的解法插頭dp,但不太好寫。

但其實這道題是裸的斯坦納樹模型。

斯坦納樹是最小生成樹的變形,在一般情況下是np問題,但在k規模較少時可以用狀壓dp求解。

我們可以設dp[i][j][s]表示以(i,j)為根,覆蓋關鍵點集合為s時的最小代價。

對於這個狀態內部的更新,我們可以對s列舉子集,相當於把聯通塊拆成兩部分再合併起來,dp[i][j][s] <= dp[i][j][s]+dp[i][j][s^s]。其中s是子集。

對於這個狀態對外的更新,我們可以對和根有連邊的點轉移,dp[i'][j'][s']=dp[i][j][s]+a[i][j]。其實令s=s『也可以,反正到了s『時也得更新。

這種dp方法的好處就是只保留了乙個轉移點,降掉了我們列舉轉移點的複雜度。

**

#include#include

#include

#include

#include

#define mm make_pair

#define n 11

using

namespace

std;

queue

int,int> >q;

int ans,dp[n][n][1

<<10

],n,m,a[n][n],tot;

bool

tag[n][n];

const

int dx[4]=;

const

int dy[4]=;

struct

nodepre[n][n][

1<<10

];inline

void spfa(int x,int y,int

s); q.push(mm(vx,vy));}}

}}inline

void findans(int x,int y,int

s)int

main()

int ma=(1

<1

;

for(int s=0;s<=ma;++s);

}spfa(i,j,s);}}

int ans=2e9,prx,pry;

for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)

if(dp[i][j][ma]

findans(prx,pry,ma);

cout

for(int i=1;i<=n;++i)

puts(

"");

}return0;

}

view code

Wc2008 遊覽計畫 斯坦納樹

斯坦納樹的問題模型是 有乙個圖,要求保留圖中最少的邊 最小的邊權和使得某k個點相互連通。最小生成樹是斯坦納樹的一種特殊情況。我們用f i j s 表示方格中i,j位置與各個景點之間的聯通情況。如果景點數為3時,111表示全部聯通,101表示第二個景點沒有聯通。當然第x個景點的 f i j 1 狀態怎...

WC2008遊覽計畫(BZOJ2595)

傳送門 time limit 10 sec memory limit 256 mbsec special judge submit status 第一行有兩個整數,n和 m,描述方塊的數目。接下來 n行,每行有 m 個非負整數,如果該整數為 0,則該方塊為乙個景點 否則表示控制該方塊至少需要的志願者...

2595 Wc2008 遊覽計畫

time limit 10 sec memory limit 256 mbsec special judge submit 1312 solved 602 submit status discuss 第一行有兩個整數,n和 m,描述方塊的數目。接下來 n行,每行有 m 個非負整數,如果該整數為 0,...