現在我們的手頭有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 105 5 6
2 3 4
0 1 1
輸出樣例#1: 複製
5
tarjan縮點+樹形揹包(好難除錯啊啊)
1 #include2 #include3 #include4 #include5 #include6 #include7 #include89using
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的時候順便更新 ...