用tarjan+拓扑写的,不知道这样写是不是错的,只拿了40分。
#include<bits/stdc++.h>
#define N 1123451
#define int long long
using namespace std ;
int n , m , dfs[N] , low[N] , tot=0 , dp[N] , cnt=0 , wh[N] , W[N] , V[N] , in[N] ;
bool vis[N] ;
pair<int,int> v[N] ;
stack<int> st ;
set<int> s[N] ;
struct node{
int to , next ;
};
struct Graph{
node e[N] ;
int cnt=0 , head[N] ;
void newnet(int u,int v){
e[cnt].to = v ;
e[cnt].next = head[u] ;
head[u] = cnt++ ;
}
void clear(){
memset(head,-1,sizeof head) ;
}
}e,dag;
void tarjan(int u){
dfs[u] = low[u] = ++tot ;
st.push(u) ;
vis[u] = 1 ;
for(int i=e.head[u];~i;i=e.e[i].next){
int x=e.e[i].to ;
if(!dfs[x]){
tarjan(x) ;
low[u] = min(low[x],low[u]) ;
}else if(vis[x]) low[u] = min(low[u],dfs[x]) ;
}
if(low[u]==dfs[u]){
int temp=0 ;
cnt++ ;
while(temp!=u){
temp = st.top() ;
st.pop() ;
v[cnt].first += W[temp] ;
v[cnt].second += V[temp] ;
wh[temp] = cnt ;
vis[temp] = 0 ;
}
}
}
void f(int u){
for(int i=e.head[u];~i;i=e.e[i].next){
int x=e.e[i].to ;
if(wh[x]==wh[u]||s[wh[u]].count(wh[x])||s[wh[x]].count(wh[u])) continue ;
dag.newnet(wh[u],wh[x]) ;
in[wh[x]]++ ;
s[wh[u]].insert(wh[x]) ;
s[wh[x]].insert(wh[u]) ;
f(x) ;
}
}
struct node_three{
int first , second , third ;
};
signed main(){
e.clear() , dag.clear() ;
cin >> n >> m ;
for(int i=1;i<=n;i++) scanf("%lld",W+i) ;
for(int i=1;i<=n;i++) scanf("%lld",V+i) ;
for(int i=1;i<=n;i++){
int d ;
scanf("%lld",&d) ;
if(!d) continue ;
e.newnet(d,i) ;
}
for(int i=1;i<=n;i++) if(!dfs[i]) tarjan(i) ;
for(int i=1;i<=n;i++) f(i) ;
queue<node_three> q ;
for(int i=1;i<=cnt;i++) if(!in[i]) q.push(node_three{i,v[i].first,v[i].second}) ;
while(!q.empty()){
node_three u=q.front() ;
q.pop() ;
for(int i=m;i>=u.second;i--) dp[i] = max(dp[i],dp[i-u.second]+u.third) ;
for(int i=dag.head[u.first];~i;i=dag.e[i].next){
int x=dag.e[i].to ;
in[x]-- ;
if(!in[x]) q.push(node_three{x,v[x].first+u.second,v[x].second+u.third}) ;
}
}
cout << dp[m] ;
return 0 ;
}