HAOI2010 軟體安裝

來源:互聯網
上載者:User

標籤:www   code   typedef   show   告訴   print   目的   ref   stream   

傳送門

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

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

交上去一看只有10分……

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

看一下代碼。

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<cmath>#include<set>#include<queue>#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(){    int ans = 0,op = 1;    char ch = getchar();    while(ch < ‘0‘ || ch > ‘9‘)    {    if(ch == ‘-‘) op = -1;    ch = getchar();    }    while(ch >= ‘0‘ && ch <= ‘9‘)    {    ans *= 10;    ans += ch - ‘0‘;    ch = getchar();    }    return ans * op;}struct node{    int next,to,from;}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;int rdeg[M],tot;bool vis[M];void add(int x,int y){    e[++ecnt].to = y;    e[ecnt].next = head[x];    e[ecnt].from = x;    head[x] = ecnt;}void tarjan(int x){    low[x] = dfn[x] = ++idx;    stack[++top] = x,vis[x] = 1;    for(int i = head[x];i;i = e[i].next)    {    if(!dfn[e[i].to]) tarjan(e[i].to),low[x] = min(low[x],low[e[i].to]);    else if(vis[e[i].to]) low[x] = min(low[x],dfn[e[i].to]);    }    if(low[x] == dfn[x])    {    int p;    cnt++;    while((p = stack[top--]))    {        scc[p] = cnt,vis[p] = 0,v[cnt] += v[p],w[cnt] += w[p];        if(p == x) break;    }    }}void rebuild(){    rep(i,1,ecnt)    {    int r1 = scc[e[i].from],r2 = scc[e[i].to];    if(r1 != r2) add(r2,r1),rdeg[r1]++;    }    rep(i,n+1,cnt)    {    dp[i][0] = v[i];    if(!rdeg[i]) add(0,i);    }}void dfs(int x,int fa){    for(int i = head[x];i;i = e[i].next)    {    int t = e[i].to;    if(t == fa) continue;    dfs(t,x);    per(j,m,1)    {        rep(p,0,j-w[t]) dp[x][j] = max(dp[x][j],dp[x][j-p-w[t]] + dp[t][p]);    }    //rep(j,0,m) printf("%d ",dp[x][j]);enter;    //printf("#%d %d\n",x,dp[x][0]);    }}int main(){    n = read(),m = read();    rep(i,1,n) w[i] = read();    rep(i,1,n) v[i] = read();    rep(i,1,n)    {    x = read();    if(x != 0) add(i,x);    }    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]);    return 0;}

 

HAOI2010 軟體安裝

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.