P2515 [HAOI2010] 软件安装

 

 

:::若 add(0,i) 会影响缩点

:::add2-> 缩点 (单个点 也可以是 缩点 ) 然后构造0 ->构造树

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------debug\n");
using namespace std;
const int maxn=1e3+10;

int w[maxn],v[maxn],d[maxn];
int head1[maxn],to1[maxn<<1],nxt1[maxn<<1],tot1,head2[maxn],to2[maxn<<1],nxt2[maxn<<1],tot2;
int dfn[maxn],low[maxn],dfstm,st[maxn],top,co[maxn],col;
int rd[maxn],val[maxn],cost[maxn],f[maxn][maxn];
int n,m;

void add1(int u,int v){
    to1[++tot1]=v;nxt1[tot1]=head1[u];head1[u]=tot1;//!!!!!!! to->v
}
void add2(int u,int v){
    to2[++tot2]=v;nxt2[tot2]=head2[u];head2[u]=tot2;
}

void tarjan(int u)
{
    dfn[u]=low[u]=++dfstm; st[++top]=u;
    for(int i=head1[u];i;i=nxt1[i])
    {
        int v=to1[i];
        if(dfn[v]==0){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(co[v]==0) low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u])
    {
        co[u]=++col;
        while(st[top]!=u){
            co[st[top]]=col;
            top--;
        }
        top--;
    } 
}

void dfs(int u)//树形结构 单向边 不需要 judge faa 
{
    for(int i=cost[u];i<=m;i++) f[u][i]=val[u];
    
    for(int i=head2[u];i;i=nxt2[i])
    {
        int v=to2[i];
        dfs(v);
        for(int j=m;j>=0;j--){
            for(int k=0;k<=j-cost[u];k++){
                f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);//f[u][j-k]已经推出来 了 
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=1;i<=n;i++) cin>>v[i];
    for(int i=1;i<=n;i++){
        cin>>d[i]; 
        if(d[i]!=0) add1(d[i],i);
    }
    for(int i=1;i<=n;i++) if(dfn[i]==0) tarjan(i);
    
    for(int i=1;i<=n;i++){
        val[co[i]]+=v[i],cost[co[i]]+=w[i];//!!!!!!!!+= 
        if(co[i]!=co[d[i]]&&d[i]!=0){//若 add(0,i) 会影响缩点  
            add2(co[d[i]],co[i]);//add2-> 缩点 (单个点 也可以是 缩点 ) 然后构造0 ->构造树 
            rd[co[i]]++;
        }
    } 
    val[0]=0,cost[0]=0;
    for(int i=1;i<=col;i++) if(rd[i]==0) add2(0,i);
    //ddd
    dfs(0);
    //for(int i=1;i<=n;i++) cout<<i<<"->"<<co[i]<<"->"<<rd[co[i]]<<endl;
    
    cout<<f[0][m]<<'\n';//<- add2 + dfs 
    
    return 0;
}
View Code

 

 
posted @ 2023-08-15 00:29  JMXZ  阅读(9)  评论(0)    收藏  举报