hihocoder #1069 : 最近公共祖先·三(ST求LCA)
题目:http://hihocoder.com/problemset/problem/1069?sid=1175440
思路:就是map存储求LCA,然而开始模板弄错了,wa了n次
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
using namespace std;const int N = 200005;
struct edge
{int to,nxt,d;edge(int t = 0,int n = 0,int d = 0):to(t),nxt(n),d(d){}
}E[N*2];
int n;
int head[N*2],tot,deg[N];
int cnt,vis[N],f[N*2],rk[N*2],pos[N*2],dis[N],dp[N*2][35];
//f存储节点编号,rk存储节点深度,pos记录结点第一次出现的位置
map<string,int> mp;
string mm[N];
void init()
{memset(head,-1,sizeof(head));//memset(vis,0,sizeof(vis));for(int i = 0;i < N;i++)vis[i] = dis[i] = 0;tot = cnt = 0;mp.clear();
}
void add_edge(int s,int t,int d)
{E[tot] = edge(t,head[s],d);head[s] = tot++;
}
void dfs(int u,int depth)
{vis[u] = 1;f[++cnt] = u;pos[u] = cnt;rk[cnt] = depth;for(int i = head[u];~i;i = E[i].nxt)//访问所有子结点{int v = E[i].to,w = E[i].d;if(!vis[v]){//dis[v] = dis[u] + w;dfs(v,depth+1);f[++cnt] = u;rk[cnt] = depth;}}
}
void RMQ(int n)
{for(int i = 1;i <= n;i++)dp[i][0] = i;for(int j = 1;(1<<j) <= n;j++){for(int i = 1;i+(1<<j)-1 <= n;i++){int a = dp[i][j-1],b = dp[i + (1<<j-1)][j-1];dp[i][j] = rk[a] < rk[b] ? a : b;}}
}
int query(int l,int r)
{int k = (int)(log(r - l + 1.0) / log(2.0));int a = dp[l][k],b = dp[r-(1<<k)+1][k];return rk[a] < rk[b] ? a : b;
}
int LCA(int u,int v)
{int x = pos[u],y = pos[v];if(x > y) swap(x,y);int t = query(x,y);//找到深度最小的结点编号return f[t];
}
int main()
{ios_base::sync_with_stdio(false);cin.tie(0);int t,n,m;init();cin >> n;string u,v;int num = 0;for(int i = 1;i <= n;i++){cin >> u >> v;if(mp[u] == 0)mp[u] = ++num,mm[num] = u;if(mp[v] == 0)mp[v] = ++num,mm[num] = v;//cout << mp[u] << " " << mp[v] << "\n";add_edge(mp[u],mp[v],0);add_edge(mp[v],mp[u],0);deg[mp[v]]++;}dfs(1,1);RMQ(cnt);cin >> m;while(m--){cin >> u >> v;int lca = LCA(mp[u],mp[v]);cout << mm[lca] << "\n";}return 0;
}
hihocoder #1069 : 最近公共祖先·三(ST求LCA)相关推荐
- hihoCoder week17 最近公共祖先·三 lca st表
记录dfs序列,dfn[tot] 记录第tot次访问的节点 然后查两点在dfs序中出现的第一次 id[u] id[v] 然后 找 dep[k] = min( dep[i] ) {i 属于 [id[u ...
- 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离
首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...
- 最近公共祖先-三(RMQ-ST)
描述 上上回说到,小Hi和小Ho使用了Tarjan算法来优化了他们的"最近公共祖先"网站,但是很快这样一个离线算法就出现了问题:如果只有一个人提出了询问,那么小Hi和小Ho很难决定 ...
- hihoCoder #1062 : 最近公共祖先·一
写这篇博客的原因是缅怀一下这个题WA了两个小时的时光~~~~ 原命题链接: hihoCoder; Vjudge 1062 : 最近公共祖先·一 > Time Limit:10000ms Case ...
- [hiho 17]最近公共祖先 三
题目描述 这次是使用在线算法解决这个问题. 两个节点的最近公共祖先就是这两个节点的通路上深度最浅的那个节点. 可以通过一遍深搜把树转成数组:每次经过一个节点(无论是从父节点进入还是从子节点返回)时,把 ...
- LCA倍增法 求树的最近公共祖先(模板)
LCA倍增法 求树的最近公共祖先 查询树上任意两个节点之间的路径信息,实际上就是找这两个节点的LCA,因为唯一路径就是这两个节点分别到LCA会合,所以关键问题就是求LCA,需要的路径信息可在找LCA过 ...
- luogu P3379 【模板】最近公共祖先(LCA)
lca最近公共祖先,是指两个点最近的祖先节点:求lca我知道的有三种倍增, st表,tarjan,我要介绍的是倍增,我才不会告诉你我只会这一个. 话说我学lca可真的路途曲折,在qbxt,lcy da ...
- 最近公共祖先(Lowest_Common_Ancestors)
一.基本概念 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵树上距离最近的公共祖先节点. 所以LC ...
- 【图论】—— 最近公共祖先(LCA)
给定一颗树,若节点 z 既是 节点 x 的祖先, 也是节点 y 的祖先,那么称 z 为 x.y 的公共祖先. 在 x.y 的所有公共祖先中,深度最大的一个称为 x.y 的最近公共祖先, 也称 LCA( ...
最新文章
- OpenCV中的二进制鲁棒独立基本特征——BRIEF
- fetch 跨域请求
- 线程属性--十分重要的概念
- Cocos Creator实现的《点我+1》
- 构建根文件系统之busybox(四)完善
- python判断是否是英文字母_用python如何判断字符串是纯英文
- Fedora 23 U盘启动出现“Failed to load ldlinux.c32”解决
- 每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!
- Linux中shell运行方式,linux脚本中父shell与子shell 执行的几种方式
- 汉字笔顺口诀_【小学语文知识】汉字书写笔顺口诀+书写规则
- LIRe 源代码分析 3:基本接口(ImageSearcher)
- html水平制表和垂直制表,将水平制表符转换为垂直制表符(仅限HTML和CSS,无js)
- 常用视频格式简述(RMVB\RM\WMV\ASF\AVI\MPEG1\MPEG2\MPEG4\MOV)
- 无锁编程的原理和应用
- oracle12c rac 开启hugepage
- API Gateway/API 网关(三) - Kong的使用 - 限流rate limiting(redis)
- 笑话大全API 实战项目 开心一笑app
- dram sram drom srom ddram详细解释
- Python使用嵌套循环实现图像处理算法
- ios 如何在cell中去掉_iOS-UITableViewCell三种常用编辑模式:删除,插入,移动