• tarjan求lca 模板


    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 5e5 + 10, INF = 0x7fffffff;
    const int maxm = 1e6 + 10;
    int n, m, cnt1, cnt2, c;
    int head1[maxm], head2[maxm], f[maxm], vis[maxm];
    int res[maxm];
    
    struct node
    {
        int v, next;
    }Node[maxm];
    
    struct edge
    {
        int v, id, next;
    }Edge[maxm];
    
    void add1_(int u, int v)
    {
        Node[cnt1].v = v;
        Node[cnt1].next = head1[u];
        head1[u] = cnt1++;
    }
    
    void add1(int u, int v)
    {
        add1_(u, v);
        add1_(v, u);
    }
    
    void add2_(int u, int v, int id)
    {
        Edge[cnt2].v = v;
        Edge[cnt2].id = id;
        Edge[cnt2].next = head2[u];
        head2[u] = cnt2++;
    }
    
    void add2(int u, int v, int id)
    {
        add2_(u, v, id);
        add2_(v, u, id);
    }
    
    int find(int x)
    {
        return f[x]==x?x:(f[x] = find(f[x]));
    }
    
    int lca(int u)//把整棵树的一部分看作以节点x为根节点的小树 
    {
        f[u] = u;  //由于节点u被看作是根节点,所以把u的father设为它自己 
        vis[u] = 1;  //标记为已被搜索过 
        for(int i=head1[u]; i!=-1; i=Node[i].next) //遍历所有与x相连的节点 
        {
            node e = Node[i];  //若未被搜索 
            if(vis[e.v] == -1)
            {
                lca(e.v);  //以该节点为根节点搞小树 
                f[e.v] = u; //回溯回来后更新子结点的f
            }
        }
        for(int i=head2[u]; i!=-1; i=Edge[i].next)  //搜索包含节点u的所有询问
        {
            edge e = Edge[i];
            if(vis[e.v] != -1)  //如果另一节点已被搜索过  只有另一结点被搜索过 那一条路径的f才会更新
            {
                int k = find(e.v); //寻找最近公共祖先
                res[e.id] = k; 
            }
        }
    }
    
    void init()
    {
        mem(head1, -1);
        mem(head2, -1);
        mem(res, -1);
        mem(vis, -1);
        cnt1 = cnt2 = 0;
    }
    
    int main()
    {
        while(scanf("%d%d%d", &n, &m, &c) != EOF)
        {
            init();
            int u, v;
            rap(i, 1, n-1)
            {
                scanf("%d%d", &u, &v);
                add1(u, v);
            }
            rap(i, 1, m)
            {
                scanf("%d%d", &u, &v);
                add2(u, v, i);
            }
    
            lca(c);
            rap(i, 1, m)
            {
                if(res[i] == -1) printf("Not connected
    ");
                else printf("%d
    ", res[i]);
            }
        }
    
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    洛谷P1157----组合数的输出
    NOIP幂次方
    NOIP2012----借教室
    SpringBoot+Spring常用注解总结
    Spring常见问题总结
    Java 命名之道
    Redis 常见问题总结
    关于缓存的一些重要概念(Redis 前置菜)
    MySQL 高性能优化规范建议
    关于数据库中如何存储时间的一点思考
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9404612.html
Copyright © 2020-2023  润新知