HAOI2010 軟體安裝

2022-09-19 02:39:10 字數 1294 閱讀 7127

網上對這題一致好評,然而像我這種沒見過世面的,不知道什麼是好題,什麼題不好......

資料會出現環形依賴關係,環形裡面的軟體選乙個就要全選,相當於一件物品。

所以先跑tarjan,把強連通分量縮成乙個點,之後按強連通分量建圖,原圖 u->v,新邊 scc[v]->scc[u],表示安裝scc[v]以後才能裝scc[u]。

之後是樹形揹包。

這是我的第一道樹形揹包。(我的題解順序不代表寫題順序,我的題解是補得)

很沒有經驗。

第一次是按我自己簡單的思路走的,只得了30。

原因是在子樹空間分配上出了問題,導致在我的dfs過程中丟失了很多狀態。

f[u][j] 表示給以 u 為根的子樹分配  j  空間的最優值。

要列舉每乙個狀態。

第一維要列舉 j,第二維列舉 k,意義在於:當以 u 為根的子樹有 j 空間時,給 u 的子樹 v 分配 j-k 空間。

f[u][j] = max ( f[u][j] , f[u][k] + f[v][j-k] )

上述過程並沒有把根節點的貢獻算進去。

所以之後要一邊迴圈把根節點的貢獻算上。

當狀態成立當且僅當 f[u][j] 的 j>=w[u],此時 f[u][j] = f[u-w[u]] + val[u] 。

// q.c

#include#include#include#include#include#includeusing namespace std;

const int n=100+10,m=500+10;

int n,m,_weight[n],weight[n],_value[n],value[n],f[n][m],cnt,head[n];

struct edge

}ed[n];

void add_edge(int a,int b)

int dfs_clock,scc_cnt,pre[n],low[n],idx[n],in[n],g[n][n];

stacks;

void find_scc(int u) else if(!idx[e.v])

low[u]=min(low[u],pre[e.v]);

} if(low[u]==pre[u]) }}

void dfs(int u)

for(int j=m;j>=0;j--)

}void input()

}void prepare()

} }for(int i=1;i<=scc_cnt;i++) if(!in[i]) g[0][i]=true;

}int main()

HAOI2010 軟體安裝

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

HAOI2010 軟體安裝

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

HAOI2010 軟體安裝

開始沒有看懂題,以為就是個樹形依賴揹包,打完之後w40,然後才發現它會有還,要用tarjan縮完點後跑揹包,要建立乙個虛擬節點0連線所有的子圖 注意連線的位置 錯誤示範 1 for int i 1 i n i 這樣會導致0連線的不是入度為0的點 或環 2if dsn i 3 正確 1 for int...