蒟蒻10分,AC#2,求调
查看原帖
蒟蒻10分,AC#2,求调
1020186
zhouxianzhuo楼主2024/7/16 14:33

思路:去掉强连通分量,再树形01背包

#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,w[110],v[110],d[110],dfn[110],low[110],scc[110],sum[110],ans,f[110][510];
int hd[110],ne[510],to[510],ll[510],vl[510],tot;
stack<int> s;
vector<int> g[110],len[110],val[110];
void add(int x,int y,int w,int v){
	tot+=1;
	ne[tot]=hd[x];
	hd[x]=tot;
	to[tot]=y;
	ll[tot]=w;
	vl[tot]=v;
}
void dfs(int x){
	cnt+=1;
	dfn[x]=cnt;
	low[x]=cnt;
	s.push(x);
	for(int i=hd[x];i>=1;i=ne[i])
	{
		if(scc[to[i]]!=0)continue;
		if(dfn[to[i]]==0)
		{
			dfs(to[i]);
			low[x]=min(low[x],low[to[i]]);
		}
		else low[x]=min(low[x],dfn[to[i]]);
	}
	if(dfn[x]==low[x])
	{
		ans+=1;
		while(s.top()!=x)
		{
			sum[ans]+=1;
			scc[s.top()]=ans;
			s.pop();
		}
		sum[ans]+=1;
		scc[x]=ans;
		s.pop();
	}
}
void dfs_ans(int x){
	int l=g[x].size();
	for(int i=0;i<=l-1;i++)
	{
		dfs_ans(g[x][i]);
		for(int j=m;j>=len[x][i];j--)
			f[x][j]=max(f[x][j],f[g[x][i]][j-len[x][i]]+val[x][i]);
	}
}
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",&d[i]);
	for(int i=1;i<=n;i++)
		add(d[i],i,w[i],v[i]);
	for(int i=1;i<=n;i++)
		if(dfn[i]==0)dfs(i);
	sum[0]=1;
	for(int i=0;i<=n;i++)
	{
		for(int j=hd[i];j>=1;j=ne[j])
		{
			if(scc[i]!=scc[to[j]]&&sum[scc[i]]==1&&sum[scc[to[j]]]==1)
			{
				g[scc[i]].push_back(scc[to[j]]);
				len[scc[i]].push_back(ll[to[j]]);
				val[scc[i]].push_back(vl[to[j]]);
			}
		}
	}
	dfs_ans(0);
	printf("%d",f[0][m]);
	return 0;
}
2024/7/16 14:33
加载中...