HDU 6031 Innumerable Ancestors(LCA,树链剖分)

来源:互联网 发布:mac safari下载速度慢 编辑:程序博客网 时间:2024/05/28 04:53

题意: 对于给定的一棵树,树上点的数目为n,有q次询问,每次给定两个点集A,B,求MAX(LCA(u,v)),uA,vB.其中k=qi=0(size(A)+size(B))q1e6k1e6,n1e6

思路: 先对树进行剖分,然后将所有path(u,root),uA上的树链进行标记,并且记录该树链的最大深度。然后对于每个点vB,向root找到第一个被标记的树链,并返回res=MIN(mxdep[x],deep[x]),最后ans=MAX(ans,res)
总的时间复杂度为T=O(T(2n+2klog(n)))

#include<iostream>#include<map>#include<string>#include<cstring>#include <vector>#include <algorithm>#include <string.h>#include <cstdlib>#include <cctype>#include <set>#include <set>#include <queue>#include <stack>#include <cstdio>#define EPS 1e-6using namespace std;typedef long long ll;typedef pair<int, int > pii;#define sp system("pause")const int MAXN = 110010;struct Edge{    int to, next;}edge[MAXN * 2];int head[MAXN], tot;int top[MAXN];int fa[MAXN];int deep[MAXN];int num[MAXN];int son[MAXN];int pos;int mrk[MAXN];int mxdep[MAXN];int v[MAXN],ttt=0;void init(){    tot = 0;    memset(head, -1, sizeof head);    pos = 1;    memset(son, -1, sizeof son);}void addedge(int u, int v){    edge[tot].to = v;    edge[tot].next = head[u];    head[u] = tot++;}void dfs1(int u, int pre, int d){    deep[u] = d;    fa[u] = pre;    num[u] = 1;    for (int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if (v == pre)continue;        dfs1(v, u, d + 1);        num[u] += num[v];        if (son[u] == -1 || num[v] > num[son[u]])son[u] = v;    }}void dfs2(int u, int po){    top[u] = po;    if (son[u] == -1)return;    dfs2(son[u], po);    for (int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if (v != son[u] && v != fa[u])            dfs2(v, v);    }}int ans = 0;void lca(int x){    while (x)    {        if (mrk[top[x]] == 1 && mxdep[top[x]] == deep[x])break;        mrk[top[x]] = 1;        mxdep[top[x]] = max(mxdep[top[x]], deep[x]);        x = fa[top[x]];    }}int lcb(int x){    while (!mrk[top[x]])x = fa[top[x]];    return min(mxdep[top[x]], deep[x]);}void clr(int x){    while (x)    {        if (mrk[top[x]] == 0)break;        mrk[top[x]] = 0;        mxdep[top[x]] =0;        x = fa[top[x]];    }}int main(){    int n, m;    int cot = 0;    while (scanf("%d%d", &n, &m) != EOF)    {        init();        for (int i = 0; i < n - 1; i++)        {            int x, y;            scanf("%d%d", &x, &y);            addedge(x, y);            addedge(y, x);        }        dfs1(1, 0, 0);        dfs2(1, 1);        int mm = 0;        memset(mrk, 0, sizeof mrk);        memset(mxdep, 0, sizeof mxdep);        while (m--)        {            //mm++;            //if (mm >=1)break;            ttt = 0;            int x;            scanf("%d", &x);            for (int i = 0; i < x; i++)            {                int y;                scanf("%d", &y);                v[ttt++] = y;                lca(y);            }            scanf("%d", &x);            ans = 0;            for (int i = 0; i < x; i++)            {                int y;                scanf("%d", &y);                ans = max(ans, lcb(y));            }            for (int i = 0; i < ttt; i++)clr(v[i]);            printf("%d\n", ans + 1);        }    }}
0 0
原创粉丝点击