Tarjan耗时长求助玄关
查看原帖
Tarjan耗时长求助玄关
600441
ZhongYuLin楼主2023/9/11 12:45

未超时,但每个点耗时出奇的久。求调 https://www.luogu.com.cn/record/124414051

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int n,m,s,tot,xi,yi,ai,bi,
	nex[maxn],to[maxn],head[maxn],f[maxn],ans[maxn];
bool vis[maxn];
vector<pair<int,int> >ask[maxn];//first存另一个,second存询问编号 
void add1(int u,int v){
	nex[++tot]=head[u];
	head[u]=tot;
	to[tot]=v;
}
void add2(int u,int v,int i){
	ask[u].push_back({v,i});
	ask[v].push_back({u,i});
}
int find(int x){
	if(f[x]==x) return x;
	return f[x]=find(f[x]);
}
void merge(int x,int y){
	f[find(x)]=find(y);
}
void dfs(int x){
	for(int i=head[x];i;i=nex[i]){
		int y=to[i];
		if(vis[y]) continue;
		vis[y]=1;
		dfs(y);
		merge(y,x);
	}
	for(int i=0;i<ask[x].size();i++)	
		if(vis[ask[x][i].first]) 
			ans[ask[x][i].second]=find(ask[x][i].first); 
}
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int main(){
	n=read();m=read();s=read();
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<n;i++){
		xi=read();yi=read();
		add1(xi,yi);add1(yi,xi);
	}
	for(int i=1;i<=m;i++){
		ai=read();bi=read();
		add2(ai,bi,i);
	}
	vis[s]=1;
	dfs(s);
	for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}
2023/9/11 12:45
加载中...