BZOJ 2427 軟體安裝 O nm 樹形揹包

2021-08-14 16:02:20 字數 2926 閱讀 3567

time limit: 10 sec  memory limit: 128 mb

submit: 1913  solved: 757 [

submit][

status][

discuss]

現在我們的手頭有

n個軟體,對於乙個軟體

i,它要占用

wi的磁碟空間,它的價值為

vi。我們希望從中選擇一些軟體安裝到一台磁碟容量為

m計算機上,使得這些軟體的價值盡可能大(即

vi的和最大)。

但是現在有個問題:軟體之間存在依賴關係,即軟體

i只有在安裝了軟體

j(包括軟體

j的直接或間接依賴)的情況下才能正確工作(軟體

i依賴軟體

j)。幸運的是,乙個軟體最多依賴另外乙個軟體。如果乙個軟體不能正常工作,那麼它能夠發揮的作用為0。

我們現在知道了軟體之間的依賴關係:軟體

i依賴軟體

di。現在請你設計出一種方案,安裝價值盡量大的軟體。乙個軟體只能被安裝一次,如果乙個軟體沒有依賴則

di=0

,這時只要這個軟體安裝了,它就能正常工作。

第1行:

n, m

(0<=n<=100, 0<=m<=500)第

2行:w1, w2, ... wi, ..., wn

(0<=wi

<=m)第

3行:v1, v2, ..., vi, ..., vn

(0<=vi<=1000)第

4行:d1, d2, ..., di, ..., dn

(0<=di

<=n, di≠i

乙個整數,代表最大價值。

3 10

5 5 6

2 3 4

0 1 1

5day2 [

submit][

status][

discuss]

home

back

今天讀了徐持衡的《**幾類揹包題》, 學習了其中樹形dp的o(nm)做法. 具體做法大家可以看看**, 我在這裡就不作細述了.

這道題裸的樹上揹包, 但注意可能有環, 而且可能是多個圖. 所以要tarjan縮點重新建圖. 然後讓乙個虛擬節點連向每個樹作為新的根, 樹上揹包一下就好了. md發現tarjan敲錯狂wa不止身敗名裂.

先給出o(nm^2)的做法.

#includeusing namespace std;

stacks;

int n, m, num, idx, cnt, ans;

int f[205][505], scc[205], h[205], low[205], dfn[205], w[205], c[205], depend[205], cc[205], ww[205], in[205];

struct edge e[405];

inline void add(int u, int v)

void tarjan(int u)

if (low[u] == dfn[u])

}}void dfs(int u)

}int main()

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

if (!dfn[i]) tarjan(i);

num = 0, memset(h, 0, sizeof (h));

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

if (depend[i] && scc[depend[i]] != scc[i])

add(scc[depend[i]], scc[i]), in[scc[i]] = 1;

for (int i = 1; i <= n; ++ i) if (!in[i]) add(0, i);

dfs(0);

for(int i = 0; i <= m; i++) ans = max(ans, f[0][i]);

printf("%d\n", ans);

}

就是要有追求更優複雜度的演算法的精神~~ 給出o(nm)的演算法.

#includeusing namespace std;

stacks;

int n, m, num, idx, cnt, ans;

int f[205][505], scc[205], h[205], low[205], dfn[205], w[205], c[205], depend[205], cc[205], ww[205], in[205];

struct edge e[405];

inline void add(int u, int v)

void tarjan(int u)

if (low[u] == dfn[u])

}}void dfs(int u, int v)

}int main()

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

if (!dfn[i]) tarjan(i);

num = 0, memset(h, 0, sizeof (h));

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

if (depend[i] && scc[depend[i]] != scc[i])

add(scc[depend[i]], scc[i]), in[scc[i]] = 1;

for (int i = 1; i <= n; ++ i) if (!in[i]) add(0, i);

dfs(0, m);

for(int i = 0; i <= m; i++) ans = max(ans, f[0][i]);

printf("%d\n", ans);

}

bzoj2427 軟體安裝

軟體安裝 題目背景 bzoj2427 分析 樹型dp 原圖有環 並且好像有和其他部分不連通的單個環 這個題,顯然應該是一些環和一些樹放到一起,那麼顯然的對於乙個環要麼全部選擇,要麼乙個都不選,那麼我們先 tarjan 縮點一發每乙個 scc的 w為原來所有 w的和,v為原來所有的 v和,然後就成了一...

BZOJ 2427 分塊裸題

題意 sol 推薦乙個大神犇的blog,講的還是很好的 主要我喜歡他的 風格 逃 太裸沒什麼意思.雖然好些但碼碼也挺長的.還是貼那個大神的 天天看著 打的會不會好看點 include include include include include include using namespace st...

BZOJ 2427 HAOI2010 軟體安裝

time limit 10 sec memory limit 128 mb submit 2146 solved 865 submit status discuss description 現在我們的手頭有n個軟體,對於乙個軟體i,它要占用wi的磁碟空間,它的價值為vi。我們希望從中選擇一些軟體安裝...