HDU-5927 Auxiliary Set
阿新 • • 發佈:2018-11-10
先預處理出每個節點的父節點,子節點個數,深度
當一個不重要節點有兩個或以上子節點,並且有兩個或以上子樹裡有重要點,那麼它也會變為重要點
對於每次詢問先把不重要點按深度排序,然後按順序看其是否滿足以上條件
需要加一個數組儲存節點有多少子樹有重要點
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5 + 10; struct Edge { int to, nxt; } edge[2 * N]; int tot, tot0; int first[N], first0[N]; void addedge(int u, int v) { edge[tot].to = v; edge[tot].nxt = first[u]; first[u] = tot++; } int deep[N], f[N], son[N]; void init(int u, int d, int fa) { deep[u] = d; son[u] = 0; f[u] = fa; for (int i = first[u]; i != -1; i = edge[i].nxt) { int v = edge[i].to; if (v != fa) { init(v, d + 1, u); son[u]++; } } } bool cmp(int a, int b) { return deep[a] > deep[b]; } int vv[N]; int num[N]; int ans; int main() { int T, kase = 0; scanf("%d", &T); while (T--) { int n, q; scanf("%d%d", &n, &q); int a, b; tot = 0; memset(first, -1, sizeof(int) * (n + 1)); for (int i = 0; i < n - 1; i++) { scanf("%d%d", &a, &b); addedge(a, b); addedge(b, a); } printf("Case #%d:\n", ++kase); if (!q) continue; init(1, 0, 1); int m; memset(vv, 0, sizeof(int) * (n + 1)); while (q--) { scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d", &num[i]); vv[num[i]] = 0; } sort(num, num + m, cmp); ans = n - m; for (int i = 0; i < m; i++) { if (son[num[i]] - vv[num[i]] >= 2) ans++; else if (son[num[i]] - vv[num[i]] == 0) vv[f[num[i]]]++; } printf("%d\n", ans); } } return 0; }