就是一个板子,sum[lca(u, v)]++就好了。
const int LOGN = 11;
const int maxn = 1 << LOGN;
int head[maxn], nxt[maxn], pnt[maxn], ecnt;
int sum[maxn], mark[maxn];
int dep[maxn];
int fa[LOGN][maxn];
void addedge(int u,int v) {
pnt[ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt++;
}
int n, m;
void dfs(int u,int pre,int depth) {
fa[0][u] = pre;
dep[u] = depth;
for (int i = head[u];~i;i = nxt[i]) {
int v = pnt[i];
if (v == pre) continue;
dfs(v, u, depth + 1);
}
}
void build() {
for (int k = 0;k < LOGN - 1;++k) {
for (int u = 1;u <= n;++u) {
if (fa[k][u] == -1) fa[k+1][u] = -1;
else fa[k+1][u] = fa[k][fa[k][u]];
}
}
}
inline int upslope(int u,int p) {
for (int k = 0;k < LOGN - 1;++k)
if ((p >> k) & 1) u = fa[k][u];
return u;
}
inline int lca(int u,int v) {
if (dep[u] < dep[v]) swap(u, v);
u = upslope(u, dep[u] - dep[v]);
if (u == v) return u;
for (int k = LOGN - 1;k >= 0;--k) {
if (fa[k][u] != fa[k][v])
u = fa[k][u], v = fa[k][v];
}
return fa[0][u];
}
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
// clock_t _ = clock();
while(scanf("%d", &n) != EOF) {
memset(head, -1,sizeof head), ecnt = 0;
int u, v, num;
memset(mark, 0,sizeof mark);
for (int i = 1;i <= n;++i) {
scanf("%d:(%d)", &u, &num);
while(num--) {
scanf("%d", &v);
addedge(u, v), addedge(v, u);
mark[v] = 1;
}
}
scanf("%d", &m);
memset(sum, 0,sizeof sum);
for (int i = 1;i <= n;++i) {
if (!mark[i]) {
dfs(i, -1, 0);
break;
}
}
build();
while(m--) {
while(getchar() != '(');
scanf("%d%d", &u, &v);
sum[lca(u, v)]++;
while(getchar() != ')');
}
for (int i = 1;i <= n;++i)
if (sum[i]) printf("%d:%d\n",i, sum[i]);
}
// printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC);
return 0;
}