我能做
浙江理工大学月赛
题目描述
duxing201606毕业后子承父业继承了一家公司。在公司中,除了duxing201606以外的员工都有一个上司。如果X是Y的上司,Y是Z的上司,那么Y和Z都是X的下属。
duxing201606会经常分配任务给员工,duxing201606非常喜欢团队去完成任务,所以每次duxing201606给X分配任务的时候,会同时给X的所有下属都分配这个任务,该任务的编号为X。
duxing201606想知道如果下达多个命令的话,公司会不会乱套。duxing201606一共会下达3种命令:
1 x 给员工x和他的下属都分配编号为X的任务。
2 x 员工x和他的下属都完成了编号为X的任务。
3 x 输出员工x所有任务中编号最小的那个任务。 如果员工x没有任务就输出-1,否则输出最小的任务编号。
输入
第一行为 n m,代表有n个员工, duxing201606会下达m条命令( 1 <= n, m <= 5e4)。
第二行 n-1个p[i],p[i]代表的是 第 i+1 号员工的上司是谁,( 1<= p[i] <= i)。
第3行到m+2行,每一行输入一个 op x,含义如上。
输出
对于每条命令3,输出答案。
样例输入
9 9
1 2 2 1 5 5 5 8
3 1
3 6
1 5
3 5
3 6
1 1
3 6
2 1
3 6
样例输出
-1
-1
5
5
1
5
源代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,io[50100],top[50100],op,u,i,x;
int main() {
scanf("%d%d",&n,&m);
for(i=1; i<=n; i++) {
io[i]=i;
}
for(i=2; i<=n; i++) {
scanf("%d",&x);
io[i]=x;
}
while(m--) {
scanf("%d%d",&op,&u);
if(op==1) {
top[u]=1;
} else if(op==2) {
top[u]=0;
} else {
int oj=oj=0x7fffffff;
int ans=oj;
while(io[u]!=u) {
if(top[u]) {
ans=min(ans,u);
}
u=io[u];
}
if(top[u]) {
ans=min(ans,u);
}
if(ans==oj) {
printf("-1\n");
} else {
printf("%d\n",ans);
}
}
}
return 0;
}