先上模板~
/* LCA(倍增法,二分搜索):rt[i][u](i > i & 1) { u = rt[i][u]; } } if (u == v) return u; for (int i=D-1; i>=0; --i) { if (rt[i][u] != rt[i][v]) { u = rt[i][u]; v = rt[i][v]; } } return rt[0][u];}void solve(void) { DFS (1, -1, 0); for (int i=1; i
/* LCA -> RMQ: LCA (u, v) = F[id[u] <= i <= id[v]中dep[i]最小的i]; RMQ预处理复杂度O(nlogn),每次询问O (1) (dp[N<<1][D], F[N<<1], dep[N<<1], id[N])*/void DFS(int u, int fa, int d, int &k) { id[u] = k; F[k] = u; dep[k++] = d; for (int i=head[u]; ~i; i=edge[i].nex) { int v = edge[i].v; if (v == fa) continue; DFS (v, u, d + 1, k); F[k] = u; dep[k++] = d; }}int Min(int i, int j) { return dep[i] < dep[j] ? i : j;}void init_RMQ(int k) { for (int i=0; i
/* LCA离线处理,Tarjan算法,复杂度O (N+Q) 对询问次序按深搜时遍历到的节点顺序进行重组,并查集找祖先 ans[i]表示第i个询问的LCA*/void LCA(int u) { rt[u] = u; for (int i=head[u]; ~i; i=edge[i].nex) { int v = edge[i].v; if (rt[v] == -1) { LCA (v); rt[v] = u; } } for (int i=headq[u]; ~i; i=query[i].nex) { int v = query[i].v; if (rt[v] != -1) { int lca = Find (v); ans[query[i].id] = lca; } }}
推荐资源:
模版题
/************************************************* Author :Running_Time* Created Time :2015/10/5 星期一 15:12:31* File Name :POJ_1330.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include
模版题
/************************************************* Author :Running_Time* Created Time :2015/10/4 星期日 18:36:06* File Name :HDOJ_2586.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include