P2515 HAOI2010 軟體安裝

2022-04-06 18:09:18 字數 1871 閱讀 9119

現在我們的手頭有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 )

輸出格式:

乙個整數,代表最大價值

輸入樣例#1: 複製

3 10

5 5 6

2 3 4

0 1 1

輸出樣例#1: 複製

5

tarjan縮點+樹形揹包(好難除錯啊啊)

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8

9using

namespace

std;

1011

const

int n = 210;12

const

int m = 510;13

struct

edgee[m];

16int

head[n],dfn[n],low[n],st[n],bel[n];

17int

w[n],w[n],v[n],v[n],dp[n][m],ru[n];

18bool

vis[n];

19int

cnt,tn,tot,top,n,m;

20 vectors[n];

2122 inline char

nc()

26 inline int

read()

3435 inline void add_edge(int u,int

v) 38

39void tarjan(int

u) 49

else

if(vis[v])

50 low[u] =min(low[u],dfn[v]);51}

52if (low[u]==dfn[u]) while (st[top+1] !=u);61}

62}63void dfs(int

u) 73}74

75int

main()

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

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

8586

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

87for (int j=head[i]; j; j=e[j].nxt) 92}

93for (int i=1; i<=cnt; ++i)

94if (!ru[i]) s[0

].push_back(i);

95 dfs(0

);96 printf("

%d",dp[0

][m]);

97return0;

98 }

P2515 HAOI2010 軟體安裝

傻了。思路 scc 縮點,樹上揹包。提交 2次 無語。建邊建錯了 思路 關係可能會形成環,而整個環是乙個整體 要選就選環上所有點,否則整個不選 所以我們先把所有的環縮點,然後便形成了一棵樹 乙個點不可能有兩個父親 然後跑樹上揹包。include include using namespace std...

P2515 HAOI2010 軟體安裝

link 現在我們的手頭有 n 個軟體,對於乙個軟體 i 它要占用 w i 的磁碟空間,它的價值 v i 我們希望從中選擇一些軟體安裝到一台磁碟容量為 m 計算機上,使得這些軟體的價值盡可能大 即 v i 的和最大 但是現在有個問題 軟體之間存在依賴關係,即軟體i只有在安裝了軟體 j 包括軟體 j ...

P2515 HAOI2010 軟體安裝

給你 n 個可能有依賴關係的物品,物品的價值為 v i 重量為 w i 揹包大小為 m 要使裝的物品價值最大。如果確保這些依賴關係一定是棵樹的話,那麼我們就可以愉快地進行樹形dp。這裡複習一下樹形dp 這裡設 dp u j 表示以 u 為根的子樹中裝了重量為 j 的最大價值。在dfs的時候順便更新 ...