傳送門
一開始我以為這道題是乙個比較正常的分組揹包,只不過原來做的題目的限制條件是數目,這次是有體積(軟體所佔空間)的限制,但是兩者好像沒什麼差異……
於是我就仿著正常的分組揹包寫了一下,然後過了樣例。我才不會告訴你我一開始結果全是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...