题解:P11389 [COCI 2024/2025 #1] 等级 / Hijerarhija
思路
因为一棵树的本质是一个图,所以我们可以认为入度为 \(0\) 的节点就是这个树的根。
所以我们统计有几个根,以及是已经作为根的。最后去统计有多少个根就行了。
存储父子关系可以用 unordered_map。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>
using namespace std;
const int N = 3 * 1e5 + 5;
int n, m;
int in[N];
bool root[N];
unordered_map<int, int> fa[N];
int main() {
scanf("%d", &n);
for (int i = 1; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
fa[u][v] = 0; // 为了更清楚的统计,我们只计算 u -> v 这条边,即 fa[v][u]
fa[v][u] = 1;
in[v]++; // 孩子的入度加 1
}
int cnt = 0;
for (int i = 1; i <= n; i++) { // 统计
if (!in[i]) { // 入度为 0
root[i] = 1;
cnt++;
}
}
if (cnt == 1) printf("DA\n");
else printf("NE\n");
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
if (fa[u][v]) swap(u, v); // 默认 u 是 v 的父亲,否则交换
in[u]++, in[v]--;
if (root[u]) { // 本来是根的现在不是
root[u] = 0;
cnt--;
}
if (!in[v]) { // 新的根
root[v] = 1;
cnt++;
}
if (fa[u][v] == 0) fa[u][v] = 1; // 更新父子关系
else fa[u][v] = 0;
if (fa[v][u] == 0) fa[v][u] = 1;
else fa[v][u] = 0;
if (cnt == 1) printf("DA\n");
else printf("NE\n");
}
return 0;
}