题目
思路
样例:
输入:
20 7
0 1 0 3 2 3 0
2 1 6 3 10 4 3
输出:
1 3 1 7 4 7 1
8 10 11 18 11 17 18
依赖关系森林图:
****
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],b[N];
int c[N]; //前缀数组
int d[N]; //后缀数组
int n,m;
// 并查集
void find(int begin,int end)
{
//因为一个节点可能有多个孩子,我们要算最晚的时间,只能选取子树中后缀数组和最大的那个
d[end] = max(d[end], d[begin]+b[end]); //类似前缀和
if(a[end] != 0)
find(end, a[end]); //递归
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>a[i];
for(int i=1;i<=m;i++)
{
cin>>b[i];
d[i] = b[i];
}
for(int i=1;i<=m;i++) c[i]=b[i]+c[a[i]]; //时间最紧凑安排
int flag=0;
for(int i=1;i<=m;i++)
{
if(c[i]>n) flag=1;
cout<<c[i]-b[i]+1<<" ";
}
cout<<endl;
// 求后缀数组
if(!flag)
{
//从树的底端顺着树一直向上,求出数组的后缀和
for(int i=m;i>=1;i--)
{
if(a[i] != 0)
{
find(i , a[i]);
}
}
for(int i=1;i<=m;i++)
{
cout<<n-d[i]+1<<" ";
}
}
return 0;
}
//20 7
//0 1 0 3 2 3 0
//2 1 6 3 10 4 3
//1 3 1 7 4 7 1
//8 10 11 18 11 17 18