【题解】P15108 白井黑子
ExplodingKonjac · · 题解
【原题链接】
题目分析
注意到题目给了我们两个数组,又注意到两个数组可以维护一个双向链表,所以注意到我们可以用链表维护出 DFS 序。
不引起歧义地,以下我们将维护 DFS 序的链表简称为链表。
算法过程中,我们让
我们枚举
最后,从根开始跳后继,先把答案存在
代码实现
这里使用
void dfs(int n, Array& f, Array& a) {
int rt = -1;
for (int i{1}; i <= n; i++) {
if (a[i]) continue;
a.set(i, i);
for (int u{i};; u = f[u]) {
int v = f[u];
if (v == 0) {
rt = u;
break;
} else if (a[v]) {
int x = a[v];
if (x != v) {
a.set(v, u), f.set(u, v);
a.set(i, x), f.set(x, i);
} else {
a.set(v, u), f.set(u, v);
}
break;
} else {
a.set(v, u);
}
}
}
for (int u{rt}, k = 0;; u = a[u]) {
f.set(++k, u);
if (a[u] == u) break;
}
for (int k{1}; k <= n; k++) {
a.set(k, f[k]);
}
}