给你一个两个数组。a和b。长度都是n
a存值。
b存指针。
- ans+=a【i】
- 如果b【i】!=-1. 那么把a【b【i】】+=a【i】。
- 假如a【now】>0,那么把now这个位置放在前面操作,对答案的贡献越大。
它可以对a【b【now】】+=a【now】。(pre)并放入pre_order里。- 假如a【now】<0,那么就不能让它影响后面(a【b【now】】+=a【now】)。并放入post_order里。
- 显然,对于a【】>0 和 a【】<0 分别定义pre_order和post_order去存储答案。
且是倒序
(负值最后才操作)。o(n)可以dfs。
o(nlogn)可以拓扑。
写好 D F S DFS DFS.(根据问题,对自己问几个why)
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define fzhead EDGE(int _to, int _v, int _next)
#define fzbody to(_to), v(_v), next(_next)
#define mst(x,a) memset(x,a,sizeof(x))
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define FOR(i,x,y) for (register int i=(x);i<=(y);i++)
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define sz(a) (int)(a.size())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef pair<int, int>pa;
typedef pair<ll,ll>PA;
inline int read()
{
int ans=0;
char c=getchar();bool neg=false;
while(c<'0'||c>'9')
{
if(c=='-')neg=true;
c=getchar();
}
while(c>='0'&&c<='9')
{
ans=ans*10+c-'0';
c=getchar();
}
return (neg)?-ans:ans;
}
void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int maxn=2e5+10;
int head[maxn<<1], dis[maxn], vis[maxn];
int cnt,n,m;
struct EDGE
{
int to,v,next;
EDGE(){}
fzhead:fzbody{}
}e[maxn<<1];
void add(int bg, int ed, int v)
{
e[++cnt]=EDGE(ed, v, head[bg]);
head[bg]=cnt;
}
ll a[maxn],b[maxn],use[maxn];
ll ans=0;
vector<int>pre_order,post_order;
void dfs(int now){
use[now]=1;
for(int i=head[now]; i!=-1; i=e[i].next){
if(!use[e[i].to]){
dfs(e[i].to);
}
}
ans+=a[now];
if(b[now]!=-1&&a[now]>0){
a[b[now]]+=a[now];
}
if(a[now]>0)pre_order.pb(now);
else post_order.pb(now);
}
int main()
{
n=read();cnt=0;
for(int i=0; i<=n; i++)head[i]=-1;
for(int i=1; i<=n; i++)a[i]=read();
for(int i=1; i<=n; i++)b[i]=read();
for(int i=1; i<=n; i++){
if(b[i]!=-1)add(b[i],i,1);//b[i]++
}
for(int i=1; i<=n; i++){
if(!use[i])dfs(i);
}
reverse(all(post_order));
cout<<ans<<endl;
for(int i=0; i<sz(pre_order); i++)cout<<pre_order[i]<<' ';
for(int i=0; i<sz(post_order); i++)cout<<post_order[i]<<' ';
return 0;
}