ZOJ Problem Set - 1141 Closest Common Ancestors(倍增法)

来源:互联网 发布:js分割数字 编辑:程序博客网 时间:2024/06/03 19:16
#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|1const 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;}

原创粉丝点击