树形DP+tarjan=100 or 10分?
查看原帖
树形DP+tarjan=100 or 10分?
482730
aSunnyDay楼主2022/6/10 17:40

可惜我只有十分...

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
const ll N=109;
const ll M=509;
ll n,m,w[N],v[N],d[N],f[N][M],maw[N],vis[N],ans=0,dfn[N],low[N],cnt,Bcnt,Belong[N],w2[N],v2[N];
vector<ll> to[N],to2[N],B[N];
stack<ll> s;
bool ins[N];
ll read(){
	ll x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') f=((bool)(c^'-')<<1)-1,c=getchar();
	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*f;
}
void F(ll x){//任务是把所有的x求出来
//	cout<<"now:"<<x<<"\n";
	if(vis[x]) return;
	vis[x]=1;
	if(w[x]>maw[x]) return;
	for(ll i=w[x];i<=maw[x];++i) f[x][i]=v[x];
	for(ll weight=maw[x];weight>=w[x];--weight)
		for(ll i=0,v;i<to[x].size();++i){
			F(v=to[x][i]);
			for(ll mev=maw[x]-w[x];mev>=w[v];--mev)
				f[x][weight]=max(f[x][weight],f[v][mev]+f[x][weight-mev]);
		}
//	for(ll j=w[x];j<=maw[x];++j) cout<<x<<" "<<j<<":"<<f[x][j]<<"\n";
	return;
}
void dfs(ll x,ll now){
	maw[x]=now;
	for(ll i=0,v;i<to[x].size();++i)
		dfs(to[x][i],now-w[x]);
}
void tarjan(ll x,ll fa){
	dfn[x]=low[x]=++cnt;
	s.push(x);ins[x]=1;
	for(ll i=0,v;i<to2[x].size();++i)
		if(!dfn[v=to2[x][i]]) tarjan(v,x),low[x]=min(low[x],low[v]);
		else low[x]=min(low[x],dfn[v]);
	if(low[x]==dfn[x]){
		ll v;
		++Bcnt;
		do{
			v=s.top();s.pop();
			ins[v]=0;B[Bcnt].push_back(v);
			Belong[v]=Bcnt;
		}while(v^x);
	}
}
void sodian(){
	bool vis[N]={};
	for(ll i=0;i<=Bcnt;++i){
		for(ll j=0,x;j<B[i].size();++j){
			x=B[i][j];
			for(ll k=0,v,Bv;k<to2[x].size();++k){
				v=to2[x][k],Bv=Belong[v];
				if(!vis[Bv]&&Bv!=i)
					vis[Bv]=1,to[i].push_back(Bv);
			}
			for(ll k=0,v,Bv;k<to2[x].size();++k)
				v=to2[x][k],Bv=Belong[v],vis[Bv]=0;
		}
	}
	for(ll i=1;i<=n;++i)
		w[Belong[i]]+=w2[i],
		v[Belong[i]]+=v2[i];
}
int main(){
	n=read(),m=read();
	B[0].push_back(0);
	for(ll i=1;i<=n;++i) w2[i]=read();
	for(ll i=1;i<=n;++i) v2[i]=read();
	for(ll i=1,x;i<=n;++i){
		x=read();
		if(x) to2[x].push_back(i);
	}
	for(ll i=1;i<=n;++i)
		if(!dfn[i]){to2[0].push_back(i);tarjan(i,0);} 
	sodian();
	dfs(0,m);
	F(0);
//	cout<<"low:\n";
//	for(ll i=1;i<=n;++i) cout<<low[i]<<" ";
//	cout<<"\n";
//	cout<<"dfn:\n";
//	for(ll i=1;i<=n;++i) cout<<dfn[i]<<" ";
//	cout<<"\n";
//	cout<<"Belong:\n";
//	for(ll i=1;i<=n;++i) cout<<Belong[i]<<" ";
//	cout<<"\n";
//	cout<<"v:\n";
//	for(ll i=1;i<=n;++i) cout<<v[i]<<" ";
//	cout<<"\n";
//	cout<<"w:\n";
//	for(ll i=1;i<=n;++i) cout<<w[i]<<" ";
//	cout<<"\n\nB:\n";
//	for(ll i=0;i<=n;++i,cout<<"\n"){
//		cout<<i<<":";
//		for(ll j=0;j<B[i].size();++j)
//			cout<<B[i][j]<<" ";
//	}
//	cout<<"\n\nto:\n";
//	for(ll i=0;i<=n;++i,cout<<"\n"){
//		cout<<i<<":";
//		for(ll j=0;j<to[i].size();++j)
//			cout<<to[i][j]<<" ";
//	}
//	cout<<"===========================\n";
//	for(ll i=1;i<=n;++i,cout<<"\n")
//		for(ll j=0;j<=m;++j)
//			cout<<f[i][j]<<" ";
//	cout<<"===========================\n";
	for(ll i=0;i<=m;++i) ans=max(ans,f[0][i]);//f[0][m]?
	cout<<ans;
	return 0;
}

各位大佬帮帮忙吧,不行给个大样例也可以啊...

前前后后卡了十几天

2022/6/10 17:40
加载中...