谢谢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;
}