#include <utility>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <bitset>
#include <map>
#include <iterator>
using namespace std;
#define clr(a,v) memset(a,v,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int INF = 0x7f7f7f7f;
const int maxn = 811;
const int POW = 10;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int mod = 777777777;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<VVI> VVVI;
struct node {
int v, next;
node() {
}
node(int v, int next) :
v(v), next(next) {
}
} edge[maxn << 2];
int head[maxn], E;
void add_edge(int u, int v) {
edge[E] = node(v, head[u]);
head[u] = E++;
edge[E] = node(u, head[v]);
head[v] = E++;
}
struct LCA_Query {
int p[POW][maxn], d[maxn];
int v[maxn];
bool vis[maxn];
int cnt[maxn];
void dfs(int u, int pre = 0) {
p[0][u] = pre;
int i, v;
for (i = 1; i < POW; ++i) {
p[i][u] = p[i - 1][p[i - 1][u]];
}
for (i = head[u]; ~i; i = edge[i].next) {
v = edge[i].v;
if (v == pre)
continue;
d[v] = d[u] + 1;
dfs(v, u);
}
}
void init(int rt) {
clr(p, 0);
clr(cnt, 0);
d[rt] = 0;
dfs(rt, rt);
}
int find(int u, int k) {
for (int i = 0; i < POW; ++i) {
if ((k >> i) & 1)
u = p[i][u];
}
return u;
}
void query(int a, int b) {
int i;
if (d[a] > d[b])
swap(a, b);
if (d[b] > d[a])
b = find(b, d[b] - d[a]);
if (a != b) {
for (i = POW - 1; i >= 0; --i) {
if (p[i][a] != p[i][b]) {
a = p[i][a];
b = p[i][b];
}
}
a = p[0][a];
}
cnt[a]++;
}
} LCA;
bool vis[maxn];
int main() {
ios::sync_with_stdio(false);
int n, u, v, k, i, j, m, a, b;
while (~scanf("%d", &n)) {
E = 0;
clr(vis, false);
clr(head, -1);
for (i = 0; i < n; ++i) {
scanf("%d:(%d)", &u, &k);
for (j = 0; j < k; ++j) {
scanf("%d", &v);
vis[v] = true;
add_edge(u, v);
}
}
for (i = 1; i <= n; ++i) {
if (!vis[i]) {
LCA.init(i);
break;
}
}
scanf("%d", &m);
for (i = 0; i < m; ++i) {
scanf(" (%d,%d)", &a, &b);
LCA.query(a, b);
}
for (i = 1; i <= n; ++i) {
if (LCA.cnt[i]) {
printf("%d:%d\n", i, LCA.cnt[i]);
}
}
}
return 0l;
}
ZOJ Problem Set - 1141 Closest Common Ancestors(倍增法)
最新推荐文章于 2018-10-13 08:43:22 发布