hiho一下 第十五周——最近公共祖先·二(Trajan,离线LCA)

题目连接

http://hihocoder.com/problemset/problem/1067

题目大意

就是一棵树求任意两个节点的最近公共祖先。

算法描述

在题目的提示里面有比较详细的解释。这里就不多说了。这种算法的时间复杂度是O(n+q)。

在算法的实现上也有一些技巧,在参考了一些代码后写了一个比较精简的Trajan_LAC算法。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MOD = 1e9 + 7;
const int INF = 0x7fffffff;
const int N = 1e5 + 10;

map <string, int> ID;
vector <int> G[N];
vector <pair<int, int> > Query[N];
string Name[N];
int fa[N], ans[N];

int findx(int x) {
    if(fa[x] == x) return x;
    else return fa[x] = findx(fa[x]);
}
void init(){
    ID.clear();
    memset(fa, -1, sizeof(fa));
}
void LCA(int u) {
    fa[u] = u;
    for(int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        LCA(v);
        fa[v] = u;
    }
    for(int i = 0; i < Query[u].size(); i++) {
        pair <int, int> P = Query[u][i];
        if(fa[P.first] != -1) {
            ans[P.second] = findx(P.first);
        }
    }
}
int main() {
#ifdef TYH
    freopen("in.txt", "r", stdin);
#endif // TYH
    int n, m;
    scanf("%d", &n);
    string father, son;
    int tot = 1;
    init();
    for(int i = 0; i < n; i++) {
        cin >> father >> son;
        if(!ID[father]) ID[father] = tot, Name[tot++] = father;
        if(!ID[son]) ID[son] = tot, Name[tot++] = son;
        int x = ID[father], y = ID[son];
        G[x].push_back(y);
    }
    scanf("%d", &m);
    string n1, n2;
    for(int i = 0; i < m; i++) {
        cin >> n1 >> n2;
        int x = ID[n1], y = ID[n2];
        Query[x].push_back(make_pair(y, i));
        Query[y].push_back(make_pair(x, i));
    }
    LCA(1);
    for(int i = 0; i < m; i++) {
        cout << Name[ans[i]] << endl;
    }
    return 0;
}
时间: 2024-07-29 19:23:20

hiho一下 第十五周——最近公共祖先·二(Trajan,离线LCA)的相关文章

hiho一下 第二十五周(SPFA)

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋! 鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路. 不过这个鬼屋虽然很大,但是其中的道路并不算多,所以小Hi还是希望能够知道从入口到出口的最短距离是多少? 提示:Super Programming Festival Algorithm. 输入 每个测试点

hiho一下 第九十五周 数论四&#183;扩展欧几里德

题目 : 数论四·扩展欧几里德 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho周末在公园溜达.公园有一堆围成环形的石板,小Hi和小Ho分别站在不同的石板上.已知石板总共有m块,编号为 0..m-1,小Hi一开始站在s1号石板上,小Ho一开始站在s2号石板上. 小Hi:小Ho,你说我们俩如果从现在开始按照固定的间隔数同时同向移动,我们会不会在某个时间点站在同一块石板上呢? 小Ho:我觉得可能吧,你每次移动v1块,我移动v2块,我们看能不能遇上好了. 小

每周进度条(第十五周)

第十五周进度条   第十五周 所花时间 1h 代码量(行)  100 博客量(篇)  1 学到的知识 对图片的处理 在Android程序中加入图片

每周进度表(第十五周)

  第十五周 所花时间(包括上课) 5(小时) 代码量(行) 200 博客量(篇) 7 了解到的知识点 如何对界面进行美化 如何处理anroid里的图片

学习进度条(十五周)

本周主要是对于团队开发项目的修改完善.   第十五周 所花时间(包括上课) 上课2小时,课后10小时 代码量(行) 200+ 博客量 2 了解到的知识点 服务器连接GET方法

学习进度条--第十五周

  第十五周 所花时间(包括上课时间) 4小时(包括上课2小时) 代码量(行) 70 博客量(篇) 1篇 了解到的知识点 软件的开发文档具有重要作用,书面计划是精确和可以沟通的. 软件开发中应及时解决遇到问题,不然容易造成不可挽回的错误.

第十五周周总结

周数 专业学习目标 专业学习时间 新增代码量 人文方面的学习 知识技能总结 第 十 五 周 数据结构:学习与排序有关的知识 4h 300左右 练习与排序有关的习题 计算机网络:继续练习网络服务器的搭建 3h 300左右 继续练习网络服务器的搭建 WEB:继续学习个人主页相关知识点 3h 300左右 练习个人主页相关知识点

第十五周进度条

第十五周          日期  星期一   星期二   星期三   星期四   星期五   星期六   星期日  了解到的知识点   分页分为真分页和加分页:假分页是先将所需要的数据全部查询出来(坏处是第一次很慢好处是点击下一页会很快)真分页是只查询需要的那几条(比如select * from table limit(0,5))(每次运行时间一样) jsp进入页面鼠标落到指定文本框 function setfocus(){   UserName.focus();} <body ><i

信息安全系统设计基础第十五周总结

信息安全系统设计基础第十五周总结 [内容:链接汇总] 一.每周读书笔记链接汇总 [第一周读书笔记] http://www.cnblogs.com/shadow135211/p/4824555.html [第二周读书笔记] http://www.cnblogs.com/shadow135211/p/4842258.html [第三周读书笔记] http://www.cnblogs.com/shadow135211/p/4854920.html [第四周读书笔记] (读书笔记从“第一周”开始命名,为