HAOI2010 軟體安裝 強連通分量 樹上揹包

2021-08-24 18:14:43 字數 1804 閱讀 1206

題意:有n個軟體,有的軟體依賴於某些軟體,求最大空間為m時的最大收益。

題解:容易發現有些軟體互相依賴組成了乙個環。此時這些依賴關係組成的基環樹中,環沒有出邊。所以把環縮成點。此時,森林中除了縮過點的樹以外,根節點都有一條來自虛擬節點0的入邊。因此,我們從0點向每個縮過點的樹連邊,再做一次樹上揹包就行了。

#include

#include

#include

using

namespace std;

const

int maxn =

101;

const

int maxm =

501;

struct edgee[maxn]

;int n, m, w[maxn]

, v[maxn]

;int fir[maxn]

, nxt[maxn <<1]

, to[maxn <<1]

, cnt;

int dfn[maxn]

, low[maxn]

, tim;

int sta[maxn]

, vis[maxn]

, top;

int scc[maxn]

, w[maxn]

, v[maxn]

, size[maxn]

, cont;

int dp[maxn]

[maxm]

;inline

intread()

while

(ch >=

'0'&& ch <=

'9')

return k * f;

}inline

void

add_edge

(int a,

int b)

void

tarjan

(int u)

else

if(vis[v]

) low[u]

=min

(low[u]

, dfn[v]);

}if(dfn[u]

== low[u]

)while

(sta[top +1]

!= u);}

}void

dfs(

int u)}}

if(u)}}

intmain()

for(

int i =

1; i <= n; i++)if

(!dfn[i]

)tarjan

(i);

memset

(fir,-1

,sizeof

(fir)

); cnt =0;

for(

int i =

1; i <= n; i++)if

(scc[e[i]

.fr]

!= scc[e[i]

.to]

)add_edge

(scc[e[i]

.fr]

, scc[e[i]

.to]);

for(

int i =

1; i <= cont; i++)if

(size[i]

>1)

add_edge(0

, i)

;//size大於1的點被縮過

dfs(0)

;printf

("%d"

, dp[0]

[m])

;return0;

}

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...