九校聯考-DL24 涼心模擬 Day1T2 烯烴 (olefin)
阿新 • • 發佈:2018-12-14
題目描述
銀企鵝非常擅長化學。有一天他在試圖命名一個巨大的單烯烴分子的時候,想到了一個問題。
給你一棵樹,一些邊有標記,對於每條有標記的邊,在樹中找到包含這條邊的一條最長鏈,並輸出長度。
輸入輸出格式
輸入格式
第一行一個整數 表示測試點的編號。
多組資料,第二行一個整數 表示資料組數。
對於每組資料,第一行兩個整數 , 表示節點的個數,和被標記的邊的個數。
我們規定 是根,第二行 個整數給出 父親的編號,保證。
第三行 個整數範圍在 表示哪個點的父邊被標記過。
輸出格式
對於每組資料輸出一行 個整數,必須與輸入的邊順序一致,給出的是在這條邊必選的情況下樹中最長鏈的長度。
輸入輸出樣例
輸入樣例#1:
0
1
10 3
1 2 3 1 4 6 7 3 8
10 7 9
輸出樣例#1:
8 8 6
資料範圍
測試點 n ≤ m ≤ T ≤ 特殊約定 1, 2 100 n − 1 100 無 3, 4 10^5 10 100 無 5 10^5 n − 1 100 樹是一條鏈 6 10^5 n − 1 100 所有 fa_i=1 7, 8, 9, 10 10^5 n − 1 100 無
解題分析
直接預處理出子樹中最深和次深的深度, 再一遍即可。
程式碼如下:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <ctime>
#include <cmath>
#define R register
#define IN inline
#define File freopen("olefin.in", "r", stdin), freopen("olefin.out", "w", stdout)
#define W while
#define MX 100050
inline char nc()
{
static const int buflen=1e6;
static char buf[buflen],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,buflen,stdin),p1==p2)?EOF:*p1++;
}
#define gc nc()
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
for (; !isdigit(c); c = gc);
for (; isdigit(c); c = gc)
x = (x << 1) + (x << 3) + c - 48;
}
int head[MX], ans[MX], dep[MX], fir[MX], sec[MX], sta[MX];
bool mark[MX];
struct Edge {int to, nex;} edge[MX << 1];
int dot, line, cnt;
IN void add(R int from, R int to) {edge[++cnt] = {to, head[from]}, head[from] = cnt;}
void DFS(R int now)
{
if(!head[now]) return fir[now] = dep[now], void();
for (R int i = head[now]; i; i = edge[i].nex)
{
dep[edge[i].to] = dep[now] + 1;
DFS(edge[i].to);
if(fir[now] < fir[edge[i].to]) sec[now] = fir[now], fir[now] = fir[edge[i].to];
else if(sec[now] < fir[edge[i].to]) sec[now] = fir[edge[i].to];
}
}
void calc(R int now, R int mx)
{
for (R int i = head[now]; i; i = edge[i].nex)
{
R int del = mx;
if(fir[edge[i].to] == fir[now]) del = std::max(sec[now] - dep[now], mx);
else del = std::max(fir[now] - dep[now], mx);
if(mark[edge[i].to]) ans[edge[i].to] = del + fir[edge[i].to] - dep[now];
calc(edge[i].to, del + 1);
}
}
void out(R int now)
{
if(!now) return;
out(now / 10);
putchar('0' + now % 10);
}
int main(void)
{
int T, buf;
in(dot); in(T);
W (T--)
{
in(dot), in(line);
std::memset(head, cnt = 0, sizeof(head));
std::memset(fir, 0, sizeof(fir));
std::memset(sec, 0, sizeof(sec));
std::memset(mark, false, sizeof(mark));
dep[1] = 0;
for (R int i = 2; i <= dot; ++i) in(buf), add(buf, i);
for (R int i = 1; i <= line; ++i) in(buf), mark[buf] = true, sta[i] = buf;
DFS(1);
calc(1, 0);
for (R int i = 1; i <= line; ++i) out(ans[sta[i]]), putchar(' ');
if(line) puts("");
}
}