• POJ 1330 Tarjan LCA、ST表(其实可以数组模拟)


    题意:给你一棵树,求两个点的最近公共祖先。
    思路:因为只有一组询问,直接数组模拟好了。
    (写得比较乱)
    原题请戳这里

    #include <cstdio>
    #include <bitset>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int first[10005],v[10005],next[10005];
    int main()
    {
        int cas;
        scanf("%d",&cas);
        while(cas--)
        {
            bitset<10005> b;
            memset(first,-1,sizeof(first));
            int tot=1,n,x,s,e;
            scanf("%d",&n);
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&v[tot],&x);
                next[i]=first[x];
                first[x]=tot++;
            }
            scanf("%d%d",&s,&e);
            b.flip(s);
            while(first[s]!=-1)
            {
                s=v[first[s]];
                b.flip(s);
            }
            if(b.test(e))
            {
                printf("%d
    ",e);
                goto end;
            }
            while(first[e]!=-1)
            {
                e=v[first[e]];
                if(b.test(e))
                {
                    printf("%d
    ",e);
                    break;
                }
            }
            end:;
        }
    } 

    这里写图片描述

    搞个Tarjan玩玩

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int first[10005],cas,next[10005],v[10005],s,e,ans,f[10005];
    bool vis[10005];
    int find(int x)
    {
        return f[x]==x?x:f[x]=find(f[x]);
    }
    void Tarjan(int x)
    {
        f[x]=x;
        for(int i=first[x];~i;i=next[i])
        {
            Tarjan(v[i]);
            f[find(v[i])]=x;
        }
        vis[x]=1;
        if(x==s&&vis[e])
        {
             ans=find(e);
        }
        else if(x==e&&vis[s])
        {
            ans=find(s);
        }
    }
    int main()
    {
        scanf("%d",&cas);
        while(cas--)
        {
            memset(first,-1,sizeof(first));
            memset(vis,0,sizeof(vis));
            int tot=1,n,x,root;
            scanf("%d",&n);
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&x,&v[tot]);
                next[i]=first[x];
                vis[v[tot]]=1;
                first[x]=tot++;
            }
            for(int i=1;i<=n;i++)
            {
                if(!vis[i])
                {
                    root=i;
                    break;
                }
            }
            memset(vis,0,sizeof(vis));
            scanf("%d%d",&s,&e);
            Tarjan(root);
            printf("%d
    ",ans);
        }
    } 

    这里写图片描述
    (对于这道题,还是模拟大法好啊)
    如果给多组询问,就只能用Tarjan或者ST了。。
    ST的:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int cases,root,n,jyx,jyy,tot,fa[100005][19];
    int in[100005],dep[100005],first[100005],next[100005],v[100005];
    void add(int x,int y){
        v[tot]=y;
        next[tot]=first[x];
        first[x]=tot++;
    }
    void dfs(int x)
    {
        for(int i=1;i<=18;i++)
        {
            fa[x][i]=fa[fa[x][i-1]][i-1];
        }
        for(int i=first[x];~i;i=next[i])
        {
            dep[v[i]]=dep[x]+1;
            dfs(v[i]);
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=18;i>=0;i--)
        {
            if(dep[x]>=dep[y]+(1<<i))x=fa[x][i];
            if(x==y)return x;
        }
        for(int i=18;i>=0;i--)
        {
            if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
        }
        return fa[x][0];
    }
    int main()
    {
        scanf("%d",&cases);
        while(cases--){
            memset(first,-1,sizeof(first));
            memset(in,0,sizeof(in));
            tot=0;
            scanf("%d",&n);
            for(int i=1;i<n;i++){
                scanf("%d%d",&jyx,&jyy);
                fa[jyy][0]=jyx;
                add(jyx,jyy);
                in[jyy]++;
            }
            scanf("%d%d",&jyx,&jyy);
            for(int i=1;i<=n;i++)if(!in[i])root=i;
            dfs(root);
            printf("%d
    ",lca(jyx,jyy));
        }
    }

    这里写图片描述

  • 相关阅读:
    Eclipse 导入外部项目无法识别为web项目并且无法在部署到tomcat下
    Android开发-API指南-<activity-alias>[原创译文]
    深入WeakHashMap
    寻找第K大数的方法总结
    overridePendingTransition的简介
    Oracle执行CreateTableAs报ORA-600错误
    HahaMil数据库(数据库操作组件)
    List(支持按笔画排序的List类)
    关于我的网站(八零家园三周年)
    走出象牙塔之Final(2014.07.07)
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532487.html
Copyright © 2020-2023  润新知