题解 P2515 【[HAOI2010]软件安装】

下面的题解说得很好了,但是有一点非常重要且容易忽视!!

见图的时候是从Di向i建一条有向边,,重新建图的时候是从color[d[i]]向color[i]建边

原因:因为i依赖Di,所以dfs时,应先安装了(即遍历了)Di才能安装i,重新建图后一样。

代码(重新建图时和其他题解稍有区别):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2005;
int map[N][N],w[N],v[N],x[N],y[N],head[N],k=0,low[N],sta[N],top=0,dfn[N],tim=0,color[N],color_time=0,n,m,rd[N],dp[N][N],wei[N],val[N];
bool vis[N];
struct node
{
    int to,next,w;
}edge[N*4];
void add(int u,int v)
{
    edge[++k].to=v;
    edge[k].next=head[u];
    head[u]=k;
}
void tarjan(int x)
{
    low[x]=dfn[x]=++tim;
    sta[++top]=x;vis[x]=1;
    for(int i=head[x];i;i=edge[i].next)
    {
        if(!dfn[edge[i].to])tarjan(edge[i].to),low[x]=min(low[x],low[edge[i].to]);
        else if(vis[edge[i].to])low[x]=min(low[x],dfn[edge[i].to]);
    }
    if(dfn[x]==low[x])
    {
        ++color_time;
        vis[x]=false;
        while(sta[top+1]!=x)
        {
            color[sta[top]]=color_time;
            vis[sta[top--]]=false;
        }
    }
}
void dfs(int x)
{
    for(int i=wei[x];i<=m;i++)dp[x][i]=val[x];
    for(int i=head[x];i;i=edge[i].next)
    {
        dfs(edge[i].to);
        for(int j=m-wei[x];j>=0;j--)
        {
            for(int q=0;q<=j;q++)
            {
                dp[x][j+wei[x]]=max(dp[x][j+wei[x]],dp[x][j+wei[x]-q]+dp[edge[i].to][q]);
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    for(int i=1;i<=n;i++)scanf("%d",&v[i]);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&y[i]);
        if(y[i]==0)continue;
        add(y[i],i);//此处注意
    }
    for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    memset(edge,0,sizeof(edge));
    memset(head,0,sizeof(head));
    k=0;
    for(int i=1;i<=n;i++)
    {
        val[color[i]]+=v[i];wei[color[i]]+=w[i];
        if(color[i]!=color[y[i]]&&y[i]!=0)
        add(color[y[i]],color[i]),rd[color[i]]++;//此处注意
    }
    for(int i=1;i<=color_time;i++)
    if(rd[i]==0)add(color_time+1,i);
    dfs(color_time+1);
    printf("%d",dp[color_time+1][m]);
}
发布了11 篇原创文章 · 获赞 3 · 访问量 780

猜你喜欢

转载自blog.csdn.net/steve95/article/details/104215570
今日推荐