题解: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;
}
posted @ 2024-12-15 21:15  Panda_LYL  阅读(47)  评论(0)    收藏  举报