最近公共祖先--RMQ
来源:互联网 发布:创意美工设计招聘 编辑:程序博客网 时间:2024/06/14 14:48
传送门:hihoCode.1069
#include <iostream>#include <string>#include <cstdio>#include <map>#include <vector>#include <cmath>#include<algorithm>using namespace std;const int maxn = 200005;int first[maxn]; //保存该人第一次访问出现的顺序int deep[2 * maxn]; //该点的深度int vex[2 * maxn]; //每个顺序表示的编号int dp[maxn][20]; //保存最近祖先的在数组中的下标,不能保存深度最小的,因为通过深度得不到该点数组下标,就不用说编号了map<string, int> mp; //给每一个人赋值一个编号string name[maxn]; //用编号保存名字vector<int> vec[maxn]; //保存儿子int cnt = 0; //编号用到 int k = 0; //数组下标 void dfs(int x, int dep) //得到数组 {vex[++k] = x; //这里肯定访问的是新节点,因为for循环只会继续下一个未访问的节点 deep[k] = dep;first[x] = k; //所以第一次访问肯定是这里 for (int i = 0; i < vec[x].size(); i++){dfs(vec[x][i], dep + 1);vex[++k] = x; //访问儿子之后又访问自己 deep[k] = dep;}}void RMQ(){for (int i = 1; i <= k; i++) //dp[i][j]保存的是深度最小的那一个的下标 {dp[i][0] = i; //下标为i的数组往后1位深度最小的就是自己 }int a, b;for (int i = 1; i < 20; i++) //20足够了 {for (int j = 1; j <= k; j++){if (j + (1 << i) - 1 <= k){a = dp[j][i - 1];b = dp[j + (1 << (i - 1))][i - 1];dp[j][i] = deep[a] > deep[b] ? b : a; //得到深度最小的数组下标 }}}}void query(string name1, string name2) //询问 {int b = max(first[mp[name1]], first[mp[name2]]); //表示第一次访问的节点数组下标较大的一个 int a = min(first[mp[name1]], first[mp[name2]]);int k = log2(b - a + 1); //2的k次方可能不能包含b-a-1个数 int c = dp[a][k];int d = dp[b - (1 << k) + 1][k];int res = deep[c] > deep[d] ? d : c; //得到深度最小的那一个的下标 cout<< name[vex[res]] << endl; //通过编号得到结果 }int solve(string s) //给每一个字符串一个不同的编号,相当于不同的人 {if (mp.count(s) != 0){return mp[s];}name[++cnt] = s; //通过编号保存人名 return mp[s] = cnt;}int main(){//freopen("Text.txt", "r", stdin);int ncase;string name1, name2;int m, n;int f, s;cin >> m;for (int i = 0; i < m; i++){cin >> name1 >> name2;f = solve(name1);s = solve(name2);vec[f].push_back(s); //保存儿子 }dfs(1, 1);/*for (int j = 1; j <= k; j++)cout << vex[j] << " ";cout << endl;*/RMQ();cin >> n;while (n--){cin >> name1 >> name2;query(name1, name2);}return 0;}
阅读全文
0 0
- 最近公共祖先--RMQ
- 最近公共祖先与RMQ问题
- 【转载】最近公共祖先LCA:RMQ转化
- 最近公共祖先LCA:RMQ转化
- LCA最近公共祖先(RMQ、Tarjan)
- 最近公共祖先(LCA) RMQ解决
- 最近公共祖先(LCA)和RMQ问题
- POJ--1986[Distance Queries] DFS+RMQ(最近公共祖先)
- LCA问题(最近公共祖先问题)+ RMQ问题
- hdu 4547 CD 最近公共祖先lcm (dfs+rmq)
- 【算法】最近公共祖先之在线算法(RMQ-ST)
- 【NOIp复习】最近公共祖先LCA&区间最大最小RMQ
- 最近公共祖先LCA模板(Tarjan/RMQ)
- 最近公共祖先LCA
- 最近公共祖先(LCA)
- 最近公共祖先
- Lca 最近公共祖先
- 【最近公共祖先】Tree
- JS正则表达式验证数字非常全
- 移动端踩坑解决方法汇
- leetcode[Reshape the Matrix]//待整理多种解法
- 初时HTTP协议
- 朴素贝叶斯法
- 最近公共祖先--RMQ
- hdu6140(思维)
- 4 Network配置
- 使用java 实现网络爬虫 demo
- gr-osmosdr支持GNURadio的扩展
- 游戏中的设计模式二(外观模式)
- 《如果你每天都做分内的事情,那你永远不会升职》
- windows下解决mysql5中文乱码的问题
- hdu 6143 Killer Names dp