关于倍增求LCA的一个疑问
查看原帖
关于倍增求LCA的一个疑问
241102
ThisIsAName楼主2020/8/27 22:38

谢谢dalao们能点开这篇帖子

事情是这样的...

在倍增求LCA跳到同一深度的那一部分,我第一次是这样写的:

for(rg int i=LOGN ; ~i ; --i)	//~i就是i!=-1
		if(dep[fa[u][i]] > dep[v])	//只跳不合法的情况
		{
			Min(ret, st[u][i]);	//函数实现ret=min(ret, st[u][i])
			u = fa[u][i];
		}
	Min(ret, st[u][0]);	//最后再跳一步,一定能跳到深度相同
	u = fa[u][0];
	if(u == v)	return ret;

然后它WA了。啊它怎么就WA了

于是我再回顾了一下LCA的板子,发现有不一样的地方,就按照板子的思路改成了这样:

for(rg int i=LOGN ; ~i ; --i)
		if(dep[fa[u][i]] >= dep[v])	//跳到深度大于等于它的地方
		{
			Min(ret, st[u][i]);
			u = fa[u][i];
			if(u == v)	return ret;	//刚好跳到LCA(v)就退出
		}

然后它AC了。啊它怎么就AC了

于是我就来发帖子了。希望有巨佬orz可以救救我这个蒟蒻叭。

以下是完整代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define il inline
#define rg register
#define MAXN 10010
#define MAXM 50010
#define LOGN 14
#define INF 0x3f3f3f3f
using namespace std;

template <typename T> il void init(T &x)
{
	char c;
	while((c=getchar())<'0' || c>'9');
	x = c^48;
	while((c=getchar())>='0' && c<='9')	x = (x<<1) + (x<<3) + (c^48);
}

template <typename T> void wr(T x)
{
	if(x > 9)	wr(x/10);
	putchar(x%10^48);
}

template <typename T> il void outit(T x)
{
	if(x < 0)	putchar('-'), x = -x;
	wr(x);
}

struct Edge{
	int x, nex, w;
}e[MAXM<<1];

int head[MAXN], tote;

il void ae(int u, int v, int w)
{
	e[++tote].x = v;
	e[tote].w = w;
	e[tote].nex = head[u];
	head[u] = tote;
}

il void Min(int &a, int b)
{
	if(a > b)	a = b;
}

struct two_points{
	int u, v, w;
	friend il bool operator < (two_points a, two_points b)
	{
		return a.w > b.w;
	}
}tp[MAXM];

int pre[MAXN];

int find_f(int x)
{
	if(pre[x] < 0)	return x;
	return pre[x] = find_f(pre[x]);
}

il void union_f(int a, int b)
{
	int fa=find_f(a), fb=find_f(b);
	if(fa == fb)	return;
	if(pre[fa] < pre[fb])
	{
		pre[fa] += pre[fb];
		pre[fb] = fa;
	}
	else
	{
		pre[fb] += pre[fa];
		pre[fa] = fb;
	}
}

il bool judge_f(int a, int b)
{
	return find_f(a) == find_f(b);
}

int n, m, q;

int st[MAXN][LOGN+5], dep[MAXN], fa[MAXN][LOGN+5];

void get_st(int u, int pre, int val)
{
	dep[u] = dep[pre] + 1;
	fa[u][0] = pre;
	for(rg int i=1 ; i<=LOGN ; ++i)
		fa[u][i] = fa[fa[u][i-1]][i-1];
	st[u][0] = val;
	for(rg int i=1 ; i<=LOGN ; ++i)
		st[u][i] = min(st[u][i-1], st[fa[u][i-1]][i-1]);
	for(rg int i=head[u] ; i ; i=e[i].nex)
	{
		int v = e[i].x;
		if(v == pre)	continue;
		get_st(v, u, e[i].w);
	}
}

il int query(int u, int v)
{
	if(!judge_f(u, v))	return -1;
	int ret = INF;
	if(dep[v] > dep[u])	swap(u, v);
	for(rg int i=LOGN ; ~i ; --i)
		if(dep[fa[u][i]] >= dep[v])
		{
			Min(ret, st[u][i]);
			u = fa[u][i];
			if(u == v)	return ret;
		}
	/*GG*************************************************************
	for(rg int i=LOGN ; ~i ; --i)
		if(dep[fa[u][i]] > dep[v])
		{
			Min(ret, st[u][i]);
			u = fa[u][i];
		}
	Min(ret, st[u][0]);
	u = fa[u][0];
	if(u == v)	return ret;
	*******************************************************************/
	for(rg int i=LOGN ; ~i ; --i)
		if(fa[u][i] != fa[v][i])
		{
			Min(ret, st[u][i]);
			Min(ret, st[v][i]);
			u = fa[u][i];
			v = fa[v][i];
		}
	Min(ret, st[u][0]);
	Min(ret, st[v][0]);
	return ret;
} 

signed main()
{
	
	memset(pre, -1, sizeof pre);
	memset(st, 0x3f, sizeof st);
	init(n), init(m);
	for(rg int i=1 ; i<=m ; ++i)
		init(tp[i].u), init(tp[i].v), init(tp[i].w);
	sort(tp+1, tp+m+1);
	for(rg int i=1 ; i<=m ; ++i)
	{
		int x=tp[i].u, y=tp[i].v;
		if(judge_f(x, y))	continue;
		union_f(x, y);
		int w=tp[i].w;
		ae(x, y, w);
		ae(y, x, w);
	}
	get_st(1, 0, INF);
	init(q);
	for(rg int i=1;  i<=q ; ++i)
	{
		int x, y;
		init(x), init(y);
		outit(query(x, y));
		putchar('\n');
	}
	
	return 0;
}
2020/8/27 22:38
加载中...