1644. 二叉树中的最低公共祖先
1.map中查找没找到:a为一个map :a.find(x) == a.end()
你丑你就多读点书。
但是我好像不丑啊。、
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
typedef pair<int,int> PII;
unordered_map<int,int> ma; //从结点值映射到结点编号
unordered_map<int,int> pre; //从节点编号映射回结点值
const int N = 10010,M=1010,INF=1e9;
int f[N]; //并查集父节点
int vis[N]; //询问和u结点相关的所有节点时 只有vis过才将其的find设置为LCA
int lson[N],rson[N]; //左孩子 右孩子 。lson[i] rson[i] 分别表示i的左孩子和右孩子
int preorder[N],inorder[N]; //分别表示前序遍历 中序遍历
int ans[N]; //最终的结果
PII a[N]; //记录所有询问
vector<PII> query[N]; //记录所有的询问。query[i] = {j,id} 第id次询问i和j的公共祖先
int n,m;
int pivot = 0; //用来dfs模拟前序遍历 先根再左子树再右子树
void dfs(int root,int l,int r) //root表示当前根节点所在位置 l表示当前区间最左边 r表示当前区间最右边
{
if(l>=r) return; //说明l==r 中间没有元素 l和r所在结点即当前子树的根节点也是唯一结点 即叶节点
if(root>l) //l==root说明左边没有了 没有左子树
{
lson[root] = ma[preorder[++pivot]];
dfs(lson[root],l,root-1);
}
if(root<r) //r==root说明右边没有了 没有右子树
{
rson[root] = ma[preorder[++pivot]];
dfs(rson[root],root+1,r);
}
}
int find(int x)
{
if(x==f[x]) return x;
return f[x] = find(f[x]);
}
void tarjan(int u) //基于dfs的tarjan算法
{
if(lson[u])
{
tarjan(lson[u]); //先tarjan 访问到叶节点了往上翻才是正确的。
f[lson[u]] = u; //再设置
}
if(rson[u])
{
tarjan(rson[u]); //先tarjan
f[rson[u]] = u; //在设置
}
for(int i=0;i<query[u].size();i++) //判断所有的关于u结点的询问
{
int v=query[u][i].first,idx=query[u][i].second; //第idx次询问u v的LCA
if(vis[v]) //tarjan:只有访问过v结点 v结点的根节点才是u v的LCA
{
int parent = find(v);
ans[idx] = parent;
}
}
vis[u] = 1; //最后在设置vis。因为是dfs 所以只有结束了关于u的dfs才算访问完
//否则在最前面 如果这个节点还有左右子树 则还会继续向下 这个节点没有访问结束。
}
int main()
{
cin>>m>>n;
int id=0;
for(int i=1;i<=n;i++)
{
cin>>inorder[i]; //输入中序遍历序列
ma[inorder[i]]=++id; //将中序遍历序列离散化。这样中间全用离散化后的即可
pre[id] = inorder[i];
}
for(int i=1;i<=n;i++)
{
cin>>preorder[i];
f[i] = i;
}
int root = ma[preorder[1]]; //root就是根节点在中序遍历中的位置编号
dfs(root,1,n); //递归遍历建树
for(int i=1;i<=m;i++)
{
int x,y;cin>>x>>y;
a[i].first=x;
a[i].second=y;
if(ma.find(x)==ma.end()||ma.find(y)==ma.end())
ans[i] = INF;
else
{
x=ma[x];
y=ma[y];
if(x!=y)
{
query[x].push_back({y,i});
query[y].push_back({x,i});
}
else ans[i] = x;
}
}
tarjan(root);
for(int i=1;i<=m;i++)
{
int u=a[i].first,v=a[i].second;
if(ans[i]==INF)
{
if(ma.find(u)==ma.end()&&ma.find(v)==ma.end())
printf("ERROR: %d and %d are not found.\n",u,v);
else if(ma.find(u)==ma.end())
printf("ERROR: %d is not found.\n",u);
else if(ma.find(v)==ma.end())
printf("ERROR: %d is not found.\n",v);
}
else
{
int parent = pre[ans[i]];
if(parent==u)
printf("%d is an ancestor of %d.\n",u,v);
else if(parent==v)
printf("%d is an ancestor of %d.\n",v,u);
else printf("LCA of %d and %d is %d.\n",u,v,parent);
}
}
}