本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目链接:
codeforces.com/problemset/…
n个节点
第一行n个数表示b[i]是i的父节点
第二行n个数表示p[i]到根节点的距离是 第i小的
要按给的排名给边进行赋值,求出所有的边权
定义d[i]数组表示 i节点到根节点的距离
-
构造距离
p[i]到根节的距离是第i小,则构造p[i]到根节点的距离为前一个比它小的距离加一
即d[p[i]] = d[p[i-1]]+1 -
不满足情况
- 根节点祖先节点不等于根节点
- 距离是从小到大进行计算的,当前节点到根节点的距离等于前一个比它小的节点到根节点的距离加1。当然如果祖先节点到根节点的距离没有提前被计算出来,肯定无法得出祖先节点到当前节点的边权值,所以此种情况要考虑一下。
-
输出
i到b[i]的距离可以通过 求出,即到根节点的距离减去祖先节点到根节点的距离
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
void solve()
{
int n;
cin>>n;
vector<int>b(n+1),p(n+1),d(n+1,-1);
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++) cin>>p[i];
if(b[p[1]] != p[1])
{
cout<<-1<<endl;
return ;
}
d[p[1]] = 0;
for(int i=2;i<=n;i++)
{
if(d[b[p[i]]] == -1)
{
cout<<-1<<endl;
return;
}
d[p[i]] = d[p[i-1]] + 1;
}
for(int i=1;i<=n;i++)
cout<<d[i]-d[b[i]]<<" \n"[i==n];
}
int main()
{
int t;
// t = 1;
cin>>t;
while(t--) solve();
return 0;
}