1143 Lowest Common Ancestor(建树与不建两种思路)

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1143 Lowest Common Ancestor(建树与不建两种思路)相关的知识,希望对你有一定的参考价值。

目录

解法一

解法二


解法一

这题可以不建树,直接利用BST的性质:左子树<根节点<右子树,对先序序列进行遍历,如果有某个元素大于等于u,v中较小的且小于等于u,v中较大的,则可能是根节点。

这题数据弱,直接认为这样的点是根节点也AC了。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
#include<stdlib.h>
#include<time.h>
#include<vector>
#include<set>
#include<string>

using namespace std;
typedef long long LL;

const int maxn = 10007;
const int MOD = 1000000007;
const int INF = 1000000000;//INF:下确界  
const LL SUP = (1LL<<63)-1;//SUP:上确界 
const double eps = 1e-5;

int A[maxn];
int n;

map<int,int> eximp;

int main(){
	
	int pNum;
	cin>>pNum>>n;
	for(int i=0;i<n;i++){
		cin>>A[i];
		eximp[A[i]] = 1;
	}

	while(pNum--){
		int v1,v2;
		cin>>v1>>v2;
		if(eximp[v1]==0||eximp[v2]==0){
			if(eximp[v1]==1)printf("ERROR: %d is not found.\\n",v2);
			else if(eximp[v2]==1)printf("ERROR: %d is not found.\\n",v1);
			else printf("ERROR: %d and %d are not found.\\n",v1,v2);
			continue;
		}

		int LCA;
		for(int i=0;i<n;i++){
			LCA = A[i];
			if(LCA>=min(v1,v2)&&LCA<=max(v1,v2))break;
		}
		
		if(LCA==v1||LCA==v2)printf("%d is an ancestor of %d.\\n",LCA==v1?v1:v2,LCA==v1?v2:v1);
		else printf("LCA of %d and %d is %d.\\n",v1,v2,LCA);
			
			
	}

	return 0;
}

解法二

我尝试建树,然后用缩短系谱的通法找LCA,但是超时了。

代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bits/stdc++.h>
#include<stdlib.h>
#include<time.h>
#include<vector>
#include<set>
#include<string>

using namespace std;
typedef long long LL;

const int maxn = 10007;
const int MOD = 1000000007;
const int INF = 1000000000;//INF:下确界  
const LL SUP = (1LL<<63)-1;//SUP:上确界 
const double eps = 1e-5;

int A[maxn];
int n;

map<int,int> eximp;

struct Node{
	int v;
	Node *lchild,*rchild,*pa;
};

map<Node*,int> noToV;
map<int,Node*> vToNo;

void insert(int x,Node* &root){
	if(root==NULL){
		root = new Node;
		noToV[root] = x;
		vToNo[x] = root;
		root->v = x;
		root->lchild = root->rchild = root->pa = NULL;
		return; 
	}
	
	if(root->v>x){
		insert(x,root->lchild);
		if(!root->lchild->pa)root->lchild->pa = root;
	}
	if(root->v<x){
		insert(x,root->rchild);
		if(!root->rchild->pa)root->rchild->pa = root;
	}
	
}

int getLinkLen(Node* root){
	int len = 1;
	while(root->pa){
		root = root->pa;
		len ++;
	}
	return len;
}

Node* getLCA(Node* u,Node* v){
	int uLen = getLinkLen(u);
	int vLen = getLinkLen(v);
	while(uLen<vLen){
		v = v->pa;
		vLen --;
	}
	while(vLen<uLen){
		u = u->pa;
		uLen --;
	}
	while(v!=u){
		v = v->pa;
		u = u->pa;
	}
	return v;
}

int main(){
	
	int pNum;
	cin>>pNum>>n;
	for(int i=0;i<n;i++){
		cin>>A[i];
		eximp[A[i]] = 1;
	}
	
	Node* root = NULL;
	for(int i=0;i<n;i++){
		insert(A[i],root);
	}

	while(pNum--){
		int v1,v2;
		cin>>v1>>v2;
		if(eximp[v1]==0||eximp[v2]==0){
			if(eximp[v1]==1)printf("ERROR: %d is not found.\\n",v2);
			else if(eximp[v2]==1)printf("ERROR: %d is not found.\\n",v1);
			else printf("ERROR: %d and %d are not found.\\n",v1,v2);
			continue;
		}

		int LCA;
		Node* u = vToNo[v1];
		Node* v = vToNo[v2];
		LCA = noToV[getLCA(u,v)];
		
		if(LCA==v1||LCA==v2)printf("%d is an ancestor of %d.\\n",LCA==v1?v1:v2,LCA==v1?v2:v1);
		else printf("LCA of %d and %d is %d.\\n",v1,v2,LCA);
			
			
	}

	return 0;
}

结果

以上是关于1143 Lowest Common Ancestor(建树与不建两种思路)的主要内容,如果未能解决你的问题,请参考以下文章

1143. Lowest Common Ancestor (30)

A1143. Lowest Common Ancestor

PAT 1143 Lowest Common Ancestor

1143 Lowest Common Ancestor (30分)

PAT 甲级 1143 Lowest Common Ancestor

PAT 1143 Lowest Common Ancestor[难][BST性质]