BZOJ 2595 Wc2008 遊覽計畫

2021-09-07 03:47:56 字數 1091 閱讀 5825

\(n * m\)的網格,如果\(a_ = 0\)則表示景點,否則表示這裡的需要的志願者人數。求一種安排志願者的方案使得所有景點連通且志願者最少。

本題可以插頭dp,然而有乙個東西叫斯坦納樹,來學習學習。

令\(f(i, j, s)\)表示\((i, j)\)為根,連通性為\(s\)的最少志願者。則有轉移:

$$ f(i, j, s) = min \begin f(i, j, t) + f(i, j, s-t) - a_ & t \neq \varnothing, t \subset s \\ f(i', j', s) & (i, j)與(i', j')相鄰 \\ \end $$

第乙個轉移可以直接做,然而第二個轉移不是\(dag\)= =,所以我們得用最短路來求出來。

所以我們狀壓dp一下,然後每乙個狀態\(s\)先更新了第一種轉移,然後再最短路一下。

然後完了= =

如分析。

#include using namespace std;

const int n=10, m=n*n+5, oo=0x3f3f3f3f, dx=, dy=;

int n, m, a[n][n], f[n][n][1<=n || fy<0 || fy>=m)

int temp=f[x][y][s]+a[fx][fy];

if(f[fx][fy][s]>temp)

p[fx][fy][s]=hash(x, y, s);}}

vis[x][y]=0;

}fr=ta=0;

}void work()

}if(f[i][j][s]!=oo) }}

spfa(s);

}}void dfs(int i, int j, int s)

int y=h%100, x=(h%10000)/100, t=h/10000;

dfs(x, y, t);

if(i==x && j==y)

}void out() }}

}void prin()

else if(ok[i][j])

else

}puts("");

}}int main()

BZOJ 2595 Wc2008 遊覽計畫

啊 斯坦納樹 好像很厲害啊 反正我之前不會。其實不知道實用性怎麼樣 畢竟複雜度不小。大概過程就是乙個狀壓dp spfa 列舉狀態 從小狀態更新大狀態 再對當前狀態做一次像spfa一樣的鬆弛操作 下面這個人講的不錯 可以去看看 為什麼我的 又那麼短 有點擔心優美度了 有誰提一下建議嗎2333 我覺得還...

bzoj2595 Wc2008 遊覽計畫

斯坦納樹 f i zt 表示以i為根,連成的聯通塊包括那些景點 兩個轉移 f i zt f i tzt f i zt tzt a i f i zt f j zt a i i,j 相鄰 後面這個可以用spfa優化 記得先進行前乙個轉移,還有容斥減掉a i include include include...

bzoj2595 Wc2008 遊覽計畫

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