GDFZOJ 美丽树
题意:
给出一棵有n个点的树,边是有向边,定义一棵美丽子树为:一个点及其子树所有点的编号恰好为一段连续的数字则称之为美丽,现在求有多少棵美丽子树?
题解:
一段连续的数字必定有一个最大的数字和最小的数字,如果现在知道最大和最小的数是什么了,判断是否连续就可以通过找出数的个数了。。
所以需要找出:一棵子树的最大值,最小值,节点个数
代码:
#include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; const int N = 1e5 + 7; int n, c[N], r[N], root, ans, siz[N], mini[N], maxi[N]; vector <int> e[N]; void DFS (int u) { siz[u] = 1, mini[u] = u, maxi[u] = u; for (int it = 0; it < e[u].size(); ++it) { int v = e[u][it]; DFS (v); mini[u] = min (mini[u], mini[v]); maxi[u] = max (maxi[u], maxi[v]); siz[u] += siz[v]; } } int main () { scanf ("%d", &n); for (int i = 1; i < n; ++i) { int u, v; scanf ("%d%d", &u, &v); e[u].push_back(v); c[u]++, r[v]++; } for (int i = 1; i <= n; ++i) if (r[i] == 0) root = i; DFS (root); int ans = 0; for (int i = 1; i <= n; ++i) if (maxi[i] - mini[i] + 1 == siz[i]) ++ans; cout << ans << endl; return 0; }
总结:
第一眼看这个题真的是被水淹没,不知所措,但是根据极端情况切入会简单很多QAQ