#include<bits/stdc++.h> using namespace std; const int N = 2e6 + 10; int n, m, Maxdep; map<string, int> name; vector<int> mp[N]; vector<pair<int, int>> qus[N]; int ans[N]; int col[N]; int dfn[N], cnt, ct, fa[N];//cnt是dfn序, ct是颜色种类 int L[N], R[N]; int dep[N],sz[N],dg[N]; void dfs(int x, int Dep) { L[x] = ++cnt; dfn[cnt] = x; dep[x] = Dep; Maxdep = max(Maxdep, dep[x]); sz[x] = 1; int maxn = 0; for (auto y : mp[x]) { if (y == fa[x]) continue; dfs(y, Dep + 1); sz[x] += sz[y]; if (sz[y] > maxn) { maxn = sz[y]; dg[x] = y;//重儿子 } } R[x] = cnt; } set<int> cntt[N]; void dfs1(int x, int fa, bool kep) { for (auto y : mp[x]) { if (y != fa && y != dg[x]) dfs1(y, x, false); }//先做自己的所有轻儿子 if (dg[x]) dfs1(dg[x], x, true);//做重儿子并保留 for (auto y : mp[x]) if (y != fa && y != dg[x]) for (int i = L[y]; i <= R[y]; i++) cntt[dep[dfn[i]]].insert(col[dfn[i]]); cntt[dep[x]].insert(col[x]); for (auto y : qus[x]) { ans[y.second] = cntt[y.first + dep[x]].size(); } if (kep == false) for (int i = 1; i <= Maxdep; i++) cntt[i].clear(); } int main() { cin >> n; for (int i = 1; i <= n; i++) { string s; cin >> s >> fa[i]; if (!name[s]) name[s] = ++ct;//名字没出现过,那么就是一种新颜色 col[i] = name[s];//每个人对应一个颜色(名字) if(fa) mp[i].push_back(fa[i]); if(fa) mp[fa[i]].push_back(i); } for (int i = 1; i <= n; i++) if (!fa[i]) dfs(i, 1); cin >> m; for (int i = 1; i <= m; i++) { int a, b; cin >> a >> b; qus[a].push_back({ b,i }); } for (int i = 1; i <= n; i++) if (!fa[i]) dfs1(i, 0, false); for (int i = 1; i <= m; i++) cout << ans[i] << endl; }
标签:sz,cnt,Return,int,Cousins,DSU,fa,mp,dg From: https://www.cnblogs.com/Aacaod/p/17016046.html