tarjan+treedp,10pts求助
查看原帖
tarjan+treedp,10pts求助
278259
RemiliaScar1et楼主2020/9/2 17:05

RT,改着改着连样例都过不了了/kk

码风较毒求别喷

#include <bits/stdc++.h>
using namespace std;

const int N=2e3;

int head[N],ver[N],nxt[N],tot=0;
int _head[N],_ver[N],_nxt[N],_tot=0;

int n,v;
int W[N],V[N];/*占用空间 价值*/
int dfn[N],low[N],tsp=0;
int stk[N],top=0;
bool inst[N];
int id[N],scc_cnt=0,size_[N],ind[N];
int Ws[N],Vs[N];
int dp[N][N];

void add(int x,int y)
{
	ver[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void _add(int x,int y)
{
	_ver[++_tot]=y;
	_nxt[_tot]=_head[x];
	_head[x]=_tot;
}

void tarjan(int x)
{
	dfn[x]=low[x]=++tsp;
	stk[++top]=x;inst[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(!dfn[y])
		{
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(inst[y]) low[x]=min(low[x],dfn[y]);
	}
	
	if(dfn[x]==low[x])
	{
		scc_cnt++;
		int y;
		do{
			y=stk[top--];
			inst[y]=0;
			id[y]=scc_cnt;
			Ws[scc_cnt]+=W[y];//合并体积
			Vs[scc_cnt]+=V[y];//合并价值
			size_[scc_cnt]++;
		}while(y!=x);
	}
}

void dfs(int x)
{
	for(int i=Ws[x];i<=v;i++)
	{
		dp[x][i]=Vs[x];
	}
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		dfs(y);
		for(int j=v-Ws[x];j>=0;j--)
		{
			for(int k=0;k<=j;k++)
			{
				dp[x][j+Ws[x]]=max(dp[x][j+Ws[x]],dp[y][k]+dp[x][j+Ws[x]-k]);
			}
		}
	}
}

int main()
{
	scanf("%d%d",&n,&v);
	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++)
	{
		int x;
		scanf("%d",&x);
		add(x,i);
	}
	
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i]) tarjan(i);
	}
	
	for(int i=1;i<=n;i++)
	{
		for(int j=head[i];j;j=nxt[j])
		{
			int k=ver[j];
			if(id[i]!=id[k])
			{
				_add(id[i],id[k]);//建新图,缩点
				ind[id[k]]++;//统计入度
			}
		}
	}
	
	for(int i=1;i<=scc_cnt;i++)
	{
		if(!ind[i])
			_add(0,i);//超级原点
	}
	dfs(0);
	printf("%d",dp[0][v]);
	
	return 0;
}

QAQQAQ

2020/9/2 17:05
加载中...