• POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)


    Tarjan算法的详细介绍,请戳:

    http://www.cnblogs.com/chenxiwenruo/p/3529533.html

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <string>
    #include <vector>
    /*
    AC
    一开始读取数据的方式并不好,运行900多ms。
    后来参照了别人的读取方式,600+ms。
    */
    using namespace std;
    const int maxn=905;
    int n,m;
    int anc[maxn];  //记录以i为公共祖先的个数对
    int indegree[maxn];  //记录入度
    int vis[maxn];
    vector<int> query[maxn];  //存储要查询的对
    
    int head[maxn];
    int tot;
    
    struct Edge{
        int to,next;
    }edge[maxn];
    
    void add(int i,int j){
        edge[tot].next=head[i];
        edge[tot].to=j;
        head[i]=tot++;
    }
    //并查集
    struct UF{
        int fa[maxn];
        void init(){
            for(int i=0;i<=n;i++)
                fa[i]=i;
        }
        int find_root(int x){
            if(fa[x]!=x)
                fa[x]=find_root(fa[x]);
            return fa[x];
        }
        void Union(int u,int v){
            fa[v]=fa[u];
        }
    }uf;
    
    void LCA(int u){
        int v;
        for(int k=head[u];k!=-1;k=edge[k].next){
            v=edge[k].to;
            LCA(v);
            uf.Union(u,v);
        }
        vis[u]=1;
        for(int i=0;i<query[u].size();i++){
            v=query[u][i];
            if(vis[v]){
                anc[uf.fa[uf.find_root(v)]]++;
            }
        }
    }
    int main()
    {
        int u,v,num,root;
        char ch;
        while(scanf("%d",&n)!=EOF){
            tot=0;
            memset(head,-1,sizeof(head));
            memset(indegree,0,sizeof(indegree));
            for(int i=0;i<maxn;i++)
                query[i].clear();
            for(int i=1;i<=n;i++){
                scanf("%d:(%d)",&u,&num);   //scanf的读取太强了
                for(int j=1;j<=num;j++){
                    scanf("%d",&v);
                    add(u,v);
                    indegree[v]++;
                }
            }
            scanf("%d",&m);
            while(m--){//这个读取方法比较妙
                while(getchar()!='(');
                scanf("%d%d",&u,&v);
                query[u].push_back(v);
                query[v].push_back(u);
            }
            while(getchar()!=')');  //别忘了读取最后的')'
    
            //寻找根节点
            for(int i=1;i<=n;i++)
                if(!indegree[i])
                    root=i;
            memset(vis,0,sizeof(vis));
            memset(anc,0,sizeof(anc));
            uf.init();
            LCA(root);
            for(int i=1;i<=n;i++){
                if(anc[i]){
                    printf("%d:%d
    ",i,anc[i]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Elasticsearch 机制 架构 集群 选举
    《Leo the late bloomer》阿虎开窍了
    各行业发明专利排行榜
    接口响应 越来越慢
    知识产权代理 与 工作流
    MBA Business Org Responsbility Account Stock
    心理学 防内耗
    Apache Kafka Zookeeper Quorum
    The different aspect of architecture(架构的不同方面)
    hPaPaas low-code/no-code 低代码
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3529800.html
Copyright © 2020-2023  润新知