HDU-4547-离线LCA

来源:互联网 发布:网络架构图组合怎么用 编辑:程序博客网 时间:2024/06/05 10:52

题目大意:dos命令,每一步可以跳到任意子目录,但只能返回上一个根目录,问a,b之间最少需要几次dos操作;

题目解析:采用离线lca,先建树,对于一个query中u和v,如果u=v,答案是0,如果v是u的祖先,答案是两者深度之差,如果u是v的祖先,答案是1,否则就是u到lca的距离再加一;

AC代码:

#include <stdio.h>#include <cstring>#include <string>#include <iostream>#include <cmath>#include <map>using namespace std;const int MAXM = 10000010;const int MAXN = 100010;int f[MAXN];int find(int x){    return f[x] == x?x:f[x] = find(f[x]);}struct Edge{    int s;    int to;    int next;    int lca;}edge[MAXM], qedge[MAXM];int head[MAXN], qhead[MAXN];int tot, qtot;void add(int s, int u){    edge[tot].to = u;    edge[tot].next = head[s];    head[s] = tot++;}void qadd(int s, int u){    qedge[qtot].s = s;    qedge[qtot].to = u;    qedge[qtot].next = qhead[s];    qhead[s] = qtot++;    qedge[qtot].s = u;    qedge[qtot].to = s;    qedge[qtot].next = qhead[u];    qhead[u] = qtot++;}bool vis[MAXN];int dfn[MAXN];int ti;void LCA(int u){    f[u] = u;    vis[u] = true;    for (int i = head[u]; i != -1; i = edge[i].next)        if (!vis[edge[i].to]) {            dfn[edge[i].to] = dfn[u]+1;            LCA(edge[i].to);            f[edge[i].to] = u;        }    for (int i = qhead[u]; i != -1; i = qedge[i].next) {        if (vis[qedge[i].to]) {            qedge[i].lca = find(qedge[i].to);            qedge[i^1].lca = qedge[i].lca;        }    }}int abs(int x) {    return x>0?x:-x;}int main(){    int in[MAXN];    int T, n, q;    int cnt, fa;    char str1[45], str2[45];    scanf("%d", &T);    while (T--) {        scanf("%d %d", &n, &q);        map<string, int> M;        cnt = 1;        tot = qtot = 0;        ti = 0;        memset(head, 0xff, sizeof(head));        memset(qhead, 0xff, sizeof(qhead));        for (int i = 0; i <= n; ++i) {            f[i] = i;            vis[i] = false;            dfn[i] = 0;            in[i] = 0;        }        for (int i = 0; i < n-1; ++i) {            scanf("%s %s", str1, str2);            if (!M[str1]) M[str1] = cnt++;            if (!M[str2]) M[str2] = cnt++;            add(M[str2], M[str1]);            in[M[str1]]++;        }        for (int i = 0; i < q; ++i) {            scanf("%s %s", str1, str2);            qadd(M[str1], M[str2]);        }        for (int i = 1; i <= n; ++i)            if (in[i] == 0) {                fa = i;                break;            }        LCA(fa);        for (int i = 0; i < qtot; ++i)        if (i%2 == 0) {            if (qedge[i].to == qedge[i].s) puts("0");            else if (qedge[i].lca == qedge[i].to) printf("%d\n", abs(dfn[qedge[i].s]-dfn[qedge[i].to]));            else if (qedge[i].s == qedge[i].lca) puts("1");            else printf("%d\n", abs(dfn[qedge[i].s]-dfn[qedge[i].lca])+1);        }    }    return 0;}



原创粉丝点击