HAOI2010 軟體安裝

2022-05-05 18:03:09 字數 1724 閱讀 2113

傳送門

一開始我以為這道題是乙個比較正常的分組揹包,只不過原來做的題目的限制條件是數目,這次是有體積(軟體所佔空間)的限制,但是兩者好像沒什麼差異……

於是我就仿著正常的分組揹包寫了一下,然後過了樣例。我才不會告訴你我一開始結果全是0,因為我寫錯了

交上去一看只有10分……

回來發現原來這題並沒有說是一棵樹……orz,那我們來看一看每乙個環,每個環裡面所有的軟體要麼全選,要麼全不選,所以直接看成乙個強連通分量縮點,把體積和價值都合起來即可。就像爐石那張融合所以我們縮點,之後把所有入度為0的點向虛擬節點連邊,之後開始正常dp。但是我一開始發現建出來的圖是反的,這樣就行不成樹了。不過想起了tarjan求強連通分量的時候,因為我把樹建成了有向圖,所以肯定原來的起點現在還應該是起點,就把建圖反了過來,之後就神奇的ac啦!

看一下**。

#include#include

#include

#include

#include

#include

#include

#define rep(i,a,n) for(int i = a;i <= n;i++)

#define per(i,n,a) for(int i = n;i >= a;i--)

#define enter putchar('\n')

using

namespace

std;

typedef

long

long

ll;const

int m = 1005

;const

int inf = 1000000009

;const ll mod = 1e9+7

;int

read()

while(ch >= '

0' && ch <= '9'

)

return ans *op;

}struct

node

e[m<<1

];int

m,n,dp[m][m],v[m],x,y,head[m],ecnt,size[m],w[m],dfn[m],scc[m],idx,low[m],stack[m],top,cnt;

intrdeg[m],tot;

bool

vis[m];

void add(int x,int

y)void tarjan(int

x)

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

}}void

rebuild()

rep(i,n+1

,cnt)

}void dfs(int x,int

fa)

//rep(j,0,m) printf("%d ",dp[x][j]);enter;

//printf("#%d %d\n",x,dp[x][0]);}}

intmain()

cnt = n,tot =ecnt;

rep(i,

1,n) if(!dfn[i]) tarjan(i);

rebuild();

//rep(i,tot+1,ecnt) printf("%d %d\n",e[i].from,e[i].to);

dfs(0,0

); printf(

"%d\n

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