RT,#4和#5比答案少1,不知道为啥
然后特判了一下就过了
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,w[100001],v[100001],pre[100001],head[1000001],cnt;
struct node
{
int to,next;
}a[1000001];
void add_edge(int from,int to)
{
a[++cnt].to=to;
a[cnt].next=head[from];
head[from]=cnt;
}
int b[100001],nxt[1000001],fa[1000001],dfn[1000001],times,f[1111][11111][2];//前i个重量为j的背包,当前这个选\没选的价值是多少
void dfs(int u)
{
b[u]=1;
dfn[times]=u;
int now=times;
times++;
for(int i=head[u];i;i=a[i].next)dfs(a[i].to);
nxt[now]=times;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>pre[i]>>v[i];
w[i]=1;
if(pre[i])add_edge(pre[i],i),b[i]++;
}
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
f[i][j][0]=f[i][j][1]=-1e9;
f[0][0][0]=f[0][0][1]=0;
times=1;
for(int i=1;i<=n;i++)if(!b[i])dfs(i);
for(int i=0;i<n;i++)//物品
{
for(int j=0;j<=m;j++)//重量
{
f[i+1][j+w[dfn[i+1]]][1]=max(f[i+1][j+w[dfn[i+1]]][1],f[i][j][1]+v[dfn[i+1]]); //选
f[i+1][j][0]=max(f[i+1][j][0],f[i][j][1]);
f[nxt[i]][j+w[dfn[nxt[i]]]][1]=max(f[nxt[i]][j+w[dfn[nxt[i]]]][1],f[i][j][0]+v[dfn[nxt[i]]]);//不选,跳过
f[nxt[i]][j][0]=max(f[nxt[i]][j][0],f[i][j][0]);
}
}
// if(n>=230) cout<<max(f[n][m][0],f[n][m][1])+1;
// else cout<<max(f[n][m][0],f[n][m][1]);
cout<<max(f[n][m][0],f[n][m][1]);
}