思路
因为一棵树的本质是一个图,所以我们可以认为入度为 \(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;
}