MLE求调+请求升蓝
查看原帖
MLE求调+请求升蓝
826079
Autumn_Rain楼主2024/4/30 20:49

RT,这题是不是可以升蓝?我菜大佬别喷。感觉又有tarjan又有LCA的,更何况还要判断写边双还是点双,本人码了100多行还MLE了,so请求升蓝QAQ。

//自认为码风清新良好
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
int n,m,s,u[N],v[N],a,b; 
struct node{
	int nxt,to;
}e[N];
int h[N],cnt;
void add(int u,int v){
	e[++cnt].nxt=h[u];
	e[cnt].to=v;
	h[u]=cnt;
}
struct Node{
	int nxt2,to2;
}e2[N];
int h2[N],cnt2;
void add2(int u,int v){
	e2[++cnt].nxt2=h2[u];
	e2[cnt].to2=v;
	h2[u]=cnt2;
}
bool ins[N];
int dfn[N],low[N],size[N];
int tot,idx,st[N],top,bel[N]; 
void tarjan(int u,int fa){
	low[u]=dfn[u]=++tot;
	st[++top]=u;
	ins[u]=1;
	for(int i=h2[u];i;i=e2[i].nxt2){
		int v=e2[i].to2;
		if(v==fa)continue;
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(ins[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		int v;
		++idx;
		do{
			v=st[top--];
			bel[v]=idx;
			ins[v]=0;
			size[idx]++;
		}while(v!=u);
	}
}
int d[N],anc[N][20];
void init(){
	for(int j=1;j<=18;j++){
		for(int i=1;i<=n;i++){
			anc[i][j]=anc[anc[i][j-1]][j-1];
		}
	}
}
void dfs(int u,int fa){
	for(int i=h[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==fa)continue;
		anc[v][0]=u;
		d[v]=d[u]+1;
		dfs(v,u);
	}
}
int lca(int u,int v){
	if(d[u]<d[v])swap(u,v);
	for(int i=18;i>=0;i--){
		if(d[anc[u][i]]>=d[v]){
			u=anc[u][i];
		}
	}
	if(u==v)return u;
	for(int i=18;i>=0;i--){
		if(anc[u][i]!=anc[v][i]){
			u=anc[u][i];
			v=anc[v][i];
		}
	}
	return anc[u][0];
}
void write(int x){
    if(!x)return;
    write(x>>1);
    printf("%d",x&1);
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>u[i]>>v[i];
		add2(u[i],v[i]);
		add2(v[i],u[i]);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i])tarjan(i,i);
	}
	for(int i=1;i<=m;i++){
		int from=bel[u[i]],to=bel[v[i]];
		if(from!=to){
			add(from,to);
			add(to,from);
		}
	}
	dfs(1,0);
	init();
	cin>>s;
	while(s--){
		cin>>a>>b;
		a=bel[a];b=bel[b];
		write(d[a]+d[b]-2*d[lca(a,b)]+1);
		cout<<endl;
	}
	return 0;
} 

求调!

2024/4/30 20:49
加载中...