zoukankan      html  css  js  c++  java
  • hihoCoder#1067(离线算法求LCA)

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中辈分最低的一个是谁。远在美国的他们利用了一些奇妙的技术获得了国内许多人的相关信息,并且搭建了一个小小的网站来应付来自四面八方的请求。

    但正如我们所能想象到的……这样一个简单的算法并不能支撑住非常大的访问量,所以摆在小Hi和小Ho面前的无非两种选择:

    其一是购买更为昂贵的服务器,通过提高计算机性能的方式来满足需求——但小Hi和小Ho并没有那么多的钱;其二则是改进他们的算法,通过提高计算机性能的利用率来满足需求——这个主意似乎听起来更加靠谱。

    于是为了他们第一个在线产品的顺利运作,小Hi决定对小Ho进行紧急训练——好好的修改一番他们的算法。

    而为了更好的向小Ho讲述这个问题,小Hi将这个问题抽象成了这个样子:假设现小Ho现在知道了N对父子关系——父亲和儿子的名字,并且这N对父子关系中涉及的所有人都拥有一个共同的祖先(这个祖先出现在这N对父子关系中),他需要对于小Hi的若干次提问——每次提问为两个人的名字(这两个人的名字在之前的父子关系中出现过),告诉小Hi这两个人的所有共同祖先中辈分最低的一个是谁?

    提示一:老老实实分情况讨论就不会出错的啦!

    提示二:并查集其实长得很像一棵树你们不觉得么?

    输入

    每个测试点(输入文件)有且仅有一组测试数据。

    每组测试数据的第1行为一个整数N,意义如前文所述。

    每组测试数据的第2~N+1行,每行分别描述一对父子关系,其中第i+1行为两个由大小写字母组成的字符串Father_i, Son_i,分别表示父亲的名字和儿子的名字。

    每组测试数据的第N+2行为一个整数M,表示小Hi总共询问的次数。

    每组测试数据的第N+3~N+M+2行,每行分别描述一个询问,其中第N+i+2行为两个由大小写字母组成的字符串Name1_i, Name2_i,分别表示小Hi询问中的两个名字。

    对于100%的数据,满足N<=10^5,M<=10^5, 且数据中所有涉及的人物中不存在两个名字相同的人(即姓名唯一的确定了一个人),所有询问中出现过的名字均在之前所描述的N对父子关系中出现过,第一个出现的名字所确定的人是其他所有人的公共祖先。

    输出

    对于每组测试数据,对于每个小Hi的询问,按照在输入中出现的顺序,各输出一行,表示查询的结果:他们的所有共同祖先中辈分最低的一个人的名字。

    样例输入
    4
    Adam Sam
    Sam Joey
    Sam Micheal
    Adam Kevin
    3
    Sam Sam
    Adam Sam
    Micheal Kevin
    样例输出
    Sam
    Adam
    Adam

    思路:利用并查集保证求(u,v)的LCA时,若u已遍历过,那么并查集的root(u)为LCA.
    #include <iostream>
    #include <string>
    #include <vector>
    #include <map>
    using namespace std;
    const int MAXN=100005;
    struct Node{
        int to,id;
        Node(){}
        Node(int to,int id)
        {
            this->to=to;
            this->id=id;
        }
    };
    int n,m,tot,vis[MAXN],par[MAXN];
    int deg[MAXN];
    string ancestor[MAXN];
    vector<int> arc[MAXN];
    map<string,int> mp;
    map<int,string> rmp;
    vector<Node> que[MAXN];
    void prep()
    {
        for(int i=0;i<MAXN;i++)
        {
            vis[i]=0;
            par[i]=i;
        }
    }
    int fnd(int x)
    {
        if(par[x]==x)
        {
            return x;
        }
        return par[x]=fnd(par[x]);
    }
    void unite(int x,int y)
    {
        int a=fnd(x);
        int b=fnd(y);
        if(a!=b)    par[b]=a;
    }
    int getID(string name)
    {
        if(mp.find(name)==mp.end())
        {
            tot++;
            mp[name]=tot;
            rmp[tot]=name;
        }
        return mp[name];
    } 
    string getName(int ID)
    {
        return rmp[ID];
    }
    void tarjan(int u)
    {
        vis[u]=1;
        for(int i=0,size=que[u].size();i<size;i++)
        {
            Node now=que[u][i];
            if(vis[now.to])
            {
                int root=fnd(now.to);
                ancestor[now.id]=rmp[root];
            }
        }
        for(int i=0,size=arc[u].size();i<size;i++)
        {
            int to=arc[u][i];
            if(!vis[to])
            {
                tarjan(to);
                unite(u,to);
            }
        }
    }
    int main()
    {
        prep();
        cin>>n;
        for(int i=0;i<n;i++)
        {
            string fa,son;
            cin>>fa>>son;
            int IDfa=getID(fa);
            int IDson=getID(son);
            deg[IDson]++;
            arc[IDfa].push_back(IDson);
        }
        cin>>m;
        for(int i=0;i<m;i++)
        {
            string son1,son2;
            cin>>son1>>son2;
            int IDson1=getID(son1);
            int IDson2=getID(son2);
            que[IDson1].push_back(Node(IDson2,i));
            que[IDson2].push_back(Node(IDson1,i));
        }
        for(int i=1;i<MAXN;i++)
        {
            if(deg[i]==0)
            {
                tarjan(i);
                break;
            }
        }
        for(int i=0;i<m;i++)
        {
            cout<<ancestor[i]<<endl;
        }
        
        return 0;
    }
  • 相关阅读:
    跟风!发一篇我常用VS开发技巧
    引用:程序员最常犯的五大非技术性错误
    Introduction to the Oracle Database 3
    Oracle Database 12c 12大新特性详解
    Streams全库复制
    Introduction to the Oracle Database 2
    Oracle FlashBack
    Oracle Database Features 2
    Oracle Database Features
    TNSName配置小结
  • 原文地址:https://www.cnblogs.com/program-ccc/p/5780453.html
Copyright © 2011-2022 走看看