树剖MLE了3个点.
查看原帖
树剖MLE了3个点.
368749
Lancer__楼主2021/10/6 20:01
#include<bits/stdc++.h>
using namespace std;
int mod, n, m, vl[1000005];
int sq[500010];

struct tree {
	int hd[500010], vr[500010], nt[500010], tt;
	int de[500010], bh, dn[500010], fa[500010], sz[500010], bg[500010], tp[500010];
	
	void push(int x, int y) 
	{
		vr[++tt] = y; nt[tt] = hd[x]; hd[x] = tt;//建图 
	}
	
	void dfs1(int nw, int en) 
	{
		de[nw] = de[en] + 1;//处理深度 
		fa[nw] = en;//父子 
		sz[nw] = 1;//定义子树大小
		 
		for(int i = hd[nw]; i; i = nt[i]) 
		{
			int v=vr[i];
			if(v == en) continue;
			dfs1(v, nw);//继续dfs 
			sz[nw] += sz[v];//累加子树大小 
			if(bg[nw] == 0 || sz[bg[nw]] < sz[v]) bg[nw] = v;//钦定重儿子 
		}	
	}
	
	void dfs2(int nw, int t) 
	{
		dn[nw] = ++bh;//处理dfsn 
		tp[nw] = t;//t为当前链链顶 
		sq[bh] = nw;//dfn与原编号建立关系 
		if(bg[nw]) dfs2(bg[nw], t);//优先处理重儿子 
		for(int i = hd[nw]; i; i = nt[i]) 
		{
			int v=vr[i];
			if(v == fa[nw] || v == bg[nw]) continue; //略过重儿子 
			dfs2(vr[i], vr[i]);//处理轻儿子,此时轻儿子链顶为自己。 
		}
	}
	
	void LCA(int a, int b) 
	{
		while(tp[a] != tp[b]) 
		{
			if(de[tp[a]] < de[tp[b]]) swap(a, b);//保证b的链顶较浅 
			a = fa[tp[a]];//深度较大的跳至链顶的父亲 
		}
		if(de[a] > de[b]) swap(a, b);//保证a的dfn较小 
		cout<<a<<endl;
	}	
}T;

int as = 0;
int S, x, y, op, z;
int main() 
{
	scanf("%d%d%d", &n, &m, &S);
	
	for(int i=1;i<n;i++)
	{
		scanf("%d%d", &x, &y);
		T.push(x, y);
		T.push(y, x);
	} 
	T.dfs1(S, 0);
	T.dfs2(S, S);
    for(int i=1;i<=m;i++) 
	{
		int x,y;
		cin>>x>>y;
		T.LCA(x,y);
	}
	
	return 0;
}
2021/10/6 20:01
加载中...