Chinaunix首页 | 论坛 | 博客
  • 博客访问: 58505
  • 博文数量: 20
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 282
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-20 17:23
个人简介

我的博客园;http://www.cnblogs.com/geekpaul/

文章分类

全部博文(20)

文章存档

2015年(7)

2014年(13)

我的朋友

分类: C/C++

2014-12-04 23:33:28

描述

AB使用了Tarjan算法来优化了他们的最近公共祖先网站,但是很快这样一个离线算法就出现了问题:如果只有一个人提出了询问,那么AB很难决定到底是针对这个询问就直接进行计算还是等待一定数量的询问一起计算。毕竟无论是一个询问还是很多个询问,使用离线算法都是只需要做一次深度优先搜索就可以了的。

那么问题就来了,如果每次计算都只针对一个询问进行的话,那么这样的算法事实上还不如使用最开始的朴素算法呢!但是如果每次要等上很多人一起的话,因为说不准什么时候才能够凑够人——所以事实上有可能要等上很久很久才能够进行一次计算,实际上也是很慢的!

那到底要怎么办呢?在等到10分钟,或者凑够一定数量的人两个条件满足一个时就进行运算?”B想出了一个折衷的办法。

哪有这么麻烦!别忘了和离线算法相对应的可是有一个叫做在线算法的东西呢!”A笑道。

B面临的问题还是和之前一样:假设现在B现在知道了N对父子关系——父亲和儿子的名字,并且这N对父子关系中涉及的所有人都拥有一个共同的祖先(这个祖先出现在这N对父子关系中),他需要对于A的若干次提问——每次提问为两个人的名字(这两个人的名字在之前的父子关系中出现过),告诉A这两个人的所有共同祖先中辈分最低的一个是谁?

输入

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

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

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

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

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

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

输出

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

样例输入

4

Adam Sam

Sam Joey

Sam Micheal

Adam Kevin

3

Sam Sam

Adam Sam

Micheal Kevin

样例输出

Sam

Adam

Adam


点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <map>
  3. #include <string>
  4. #include <vector>
  5. #include <algorithm>

  6. using namespace std;
  7. string query(map<string, string> &m, string &name1, string &name2)
  8. {
  9.     vector<string> line1, line2;
  10.     line1.push_back(name1);
  11.     line2.push_back(name2);
  12.     while (m.count(name1))
  13.     {
  14.         line1.push_back(m[name1]);
  15.         name1 = m[name1];
  16.     }
  17.     while (m.count(name2))
  18.     {
  19.         line2.push_back(m[name2]);
  20.         name2 = m[name2];
  21.     }
  22.     reverse(line1.begin(), line1.end());
  23.     reverse(line2.begin(), line2.end());
  24.     int i = 0,pos=0;
  25.     while (i < line1.size() && i < line2.size())
  26.     {
  27.         if (line1[i] == line2[i])
  28.         {
  29.             pos = i;
  30.             i++;
  31.         }
  32.         else
  33.             break;
  34.     }
  35.     return line1[pos];
  36. }
  37. int main()
  38. {
  39.     int n;
  40.     cin >> n;
  41.     string son, father;
  42.     map<string, string> m;
  43.     for (int i = 0; i<n; i++)
  44.     {
  45.         cin >> father >> son;
  46.         m[son] = father;
  47.     }
  48.     cin >> n;
  49.     for (int i = 0; i<n; i++)
  50.     {
  51.         cin >> son >> father;
  52.         if (son == father)
  53.         {
  54.             cout << son << endl;
  55.             continue;
  56.         }
  57.         else if (m.count(son) != 0 && m[son] == father)
  58.         {
  59.             cout << father << endl;
  60.             continue;
  61.         }
  62.         else if (m.count(father) != 0 && m[father] == son)
  63.         {
  64.             cout << son << endl;
  65.             continue;
  66.         }
  67.         else
  68.         {
  69.             cout << query(m, son, father) << endl;
  70.         }
  71.     }
  72.     return 0;
  73. }


阅读(1344) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~