#ijpcanimals. [ijpc_animals]むこのどうぶつたち と しんりんのはかい (Innocent Animals and Destruction of Forests)

[ijpc_animals]むこのどうぶつたち と しんりんのはかい (Innocent Animals and Destruction of Forests)

题目翻译:

给定一个由N个顶点组成的树,每个顶点上都有从0到N-1不同整数的编号。

请实现以下过程:

  • 使用参数N和E实现过程init(N, E):

    • N -- 顶点的数量。每个顶点都有从0到N-1不同整数的编号。
    • E -- 表示边信息的二维数组。对于0 ≤ i < N-1,边i连接了两个不同的顶点E[i][0]和E[i][1]。保证E表示一棵树的结构,即从任意顶点出发都可以通过边到达其他所有顶点,并且路径是唯一的。

    此过程在第一次调用query(i)之前仅调用一次。此过程没有返回值。

  • 使用参数i实现过程query(i):

    • i -- 被摧毁的顶点的编号。

    此过程被调用N-1次。每次调用摧毁一个顶点(此摧毁是在之前摧毁的基础上进行的)。不会再次指定已经摧毁的顶点i。当摧毁一个顶点i时,删除该顶点及其连接的所有边。每次调用应该返回剩余森林(一个或多个树的集合)中顶点数最大的树的顶点数。

例如:

例1:

图1
图 1

考虑N=5,E=[[0,1],[1,2],[2,3],[3,4]]的情况。

首先,过程init以上述参数被调用。然后,过程query在每次摧毁后被调用一次。以下是调用和正确返回值的示例:

摧毁

参数

返回值

1

query(1)

3

2

query(0)

3

3

query(3)

1

4

query(4)

1

例2:

图2
图 2

考虑N=5,E=[[2,1],[0,2],[4,0],[3,0]]的情况。

首先,过程init以上述参数被调用。然后,过程query在每次摧毁后被调用一次。以下是调用和正确返回值的示例:

摧毁

参数

返回值

1

query(1)

4

2

query(2)

3

3

query(0)

1

4

query(4)

1

子任务:

子任务1(20分):

  • 1 ≤ N ≤ 1,000

子任务2(25分):

  • (仅对于此子任务)树呈直线状。
  • 1 ≤ N ≤ 100,000

子任务3(55分):

  • 1 ≤ N ≤ 100,000

实现细节:

限制条件:

  • CPU时间限制:2秒
  • 内存限制:64MB
  • 注意:对于栈的大小没有限制。使用为堆栈分配的内存计入总内存使用量。

接口(API):

  • 实现文件夹: animals/ (原型: animals.zip)
  • 参赛者需要实现的文件: animals.cpp
  • 提交文件的接口: animals.h
  • 评分程序示例: grader.cpp
  • 输入示例: grader.in.1, grader.in.2, ...
    注意:评分程序样例读取输入以以下格式:
    • 第1行:N
    • 第2行到第N行:对于0 ≤ i < N-1,第i+2行包含用空格分隔的E[i][0]和E[i][1]
    • 第N+1行:包含N-1个整数I[0],I[1],...,I[N-2](以空格分隔)。I[i]是第i次摧毁的顶点的编号。
  • 对于评分程序样例输入,期望的输出是:grader.expect.1, grader.expect.2, ...
    注意:评分程序样例以以下格式输出:
    • 第一行:用空格分隔的N-1个整数X[0]、X[1]、...、X[N-2]。X[i]是查询的第i次调用应返回的值。