倍增100分+4个TLE的看这里!!
查看原帖
倍增100分+4个TLE的看这里!!
467822
fireale楼主2023/8/3 07:37

这道题我第一次做是AC的,第二次把lca单独写成函数就100分+4个TLE了。把lca函数写进主函数即可。

第一次:

#include<iostream>
#include<cstdio>
#include<cmath>
//#include<algorithm>
//#include<cstring>
#define INF 0x3f3f3f3f
//#define int long long

using namespace std;

const int maxn=510001;//

struct edge{
	int from,to,next;
}e[maxn<<1|1];

int n,m,s,head[maxn],lca[maxn][23],dep[maxn],ec,log2_[maxn];
//depth,edge_count
bool memo[maxn];

void add(int a,int b){
	e[++ec].from=a,e[ec].to=b;
	e[ec].next=head[a],head[a]=ec;
}

void dfs(int in,int fa=0){//inside dfs() in,fa -> node_index; i -> edge_index
	if(memo[in])return;
	memo[in]=true;
	dep[in]=dep[fa]+1;
	lca[in][0]=fa;
	for(int i=1;i<=log2_[dep[in]];i++){
		lca[in][i]=lca[lca[in][i-1]][i-1];
	}
	for(int i=head[in];i;i=e[i].next){
		dfs(e[i].to,in);
	}
}

signed main(){
//	freopen("lineup.in","r",stdin);
//	freopen("lineup.out","w",stdout);
	scanf("%d%d%d",&n,&m,&s);
	for(int i=2;i<=n;i++){
		log2_[i]=log2_[i>>1]+1;
	}
	int t1,t2;
	for(int i=1;i<n;i++){
		scanf("%d%d",&t1,&t2);
		add(t1,t2);add(t2,t1);
	}
	dfs(s);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&t1,&t2);
		if(t1==t2){
			printf("%d\n",t1);
			continue;
		}
		if(dep[t1]>dep[t2])swap(t1,t2);//->dep[t1]min
		while(dep[t1]!=dep[t2]){
			t2=lca[t2][log2_[dep[t2]-dep[t1]]];
		}
		if(t1==t2){
			printf("%d\n",t1);
			continue;
		}
		for(int j=log2_[dep[t1]];j>=0;j--){
			if(lca[t1][j]!=lca[t2][j]){
				t1=lca[t1][j],t2=lca[t2][j];
			}
		}
		printf("%d\n",lca[t1][0]);
	}
	return 0;
}

第二次:

#include<iostream>
#include<cstdio>
#include<cmath>
//#include<algorithm>
//#include<cstring>
#define INF 0x3f3f3f3f
//#define int long long

using namespace std;

const int maxn=510001;//

struct edge{
	int from,to,next,w;
}e[maxn<<1|1];

int n,m,s,ec,dep[maxn],head[maxn],fa[maxn],memo[maxn],f[maxn][20],_log2[maxn];

void add(int a,int b){//,int c
	e[++ec].from=a,e[ec].to=b;//,e[ec].w=c
	e[ec].next=head[a],head[a]=ec;
}

void dfs(int in,int father=0){
	if(memo[in])return;
	memo[in]=true;
	dep[in]=dep[father]+1;
	f[in][0]=father;
	for(int i=1;i<=_log2[dep[in]];i++){
		f[in][i]=f[f[in][i-1]][i-1];
	}
	for(int i=head[in];i;i=e[i].next){
		dfs(e[i].to,in);
	}
}

int lca(int a,int b){
	if(dep[a]>dep[b])swap(a,b);
	while(dep[a]!=dep[b]){
		b=f[b][_log2[dep[b]-dep[b]]];
	}
	if(a==b)return a;
	for(int i=_log2[dep[a]];i>=0;i--){
		if(f[a][i]==f[b][i])continue;
		a=f[a][i],b=f[b][i];
	}
	return f[a][0];
}

signed main(){
//	freopen("dis.in","r",stdin);
//	freopen("dis.out","w",stdout);
	scanf("%d%d%d",&n,&m,&s);
	for(int i=2;i<=n;i++) _log2[i]=_log2[i>>1]+1;
	int t1,t2,t3;
//	for(int i=1;i<n;i++){
//		scanf("%d%d%d",&t1,&t2,&t3);
//		add(t1,t2,t3);add(t2,t1,t3);
//	}

	for(int i=1;i<n;i++){
		scanf("%d%d",&t1,&t2);
		add(t1,t2);add(t2,t1);
	}
	dfs(s);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&t1,&t2);
		printf("%d\n",lca(t1,t2));
	}
	return 0;
}

/*

*/
2023/8/3 07:37
加载中...