看下面的代码,是的,是错误的。仔细看68行,lca函数内部,
这是错误的lca:if(d[f[x][i]] != d[f[y][i]])
正确的应该是:if(f[x][i] != f[y][i])
上面的错误,会导致x,y两点可能并没有即将相遇,只是他们在同一层就会结束循环,,(其实第一次对x跑完一遍for的时候他们就在同一层了,呵呵-_-)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e4+11, M = 1e5+11, INF = 0x3f3f3f3f;
int n, m, t, kt, tot, d[N], fa[N];
int f[N][33], kfc[N][33];
int head[N], ver[M], nex[M], edge[M]; // 存最大生成树
struct aaa{
int x, y, z;
}e[M]; // 存原图
void add(int x, int y, int z){ // 最大生成树
nex[++tot] = head[x];
head[x] = tot;
edge[tot] = z;
ver[tot] = y;
}
bool cmp(aaa a, aaa b){
return a.z > b.z;
}
int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
void kruskal(){
sort(e, e + (m<<1), cmp);
for(int i=0;i<(m<<1);i++){
int x = find(e[i].x);
int y = find(e[i].y);
if(x == y) continue;
fa[x] = y;
add(e[i].x, e[i].y, e[i].z);
add(e[i].y, e[i].x, e[i].z);
}
}
void dfs(int x, int w){
d[x] = w;
for(int i=head[x]; i; i=nex[i]){
int y = ver[i];
if(d[y]) continue;
f[y][0] = x;
kfc[y][0] = edge[i];
dfs(y, w + 1);
}
}
int lca(int x, int y){
if(find(x) != find(y)) return -1;
if(d[y] > d[x]) swap(x, y);
int ans = INF;
for(int i=22;i>=0;i--)
if(d[f[x][i]] >= d[y]){
ans = min(ans, kfc[x][i]);
x = f[x][i];
} if(x == y) return ans;
for(int i=22;i>=0;i--)
if(d[f[x][i]] != d[f[y][i]]){
ans = min(ans, min(kfc[x][i], kfc[y][i]));
x = f[x][i]; y = f[y][i];
} return min(ans, min(kfc[x][0], kfc[y][0]));
}
int main(){
int x, y, z, t;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) fa[i] = i;
for(int i=0;i<m;i++){
scanf("%d%d%d",&x,&y,&z);
e[i] = {x, y, z};
e[i+m] = {y, x, z};
}
kruskal();
for(int i=1;i<=n;i++) if(!d[i]) dfs(i, 1);
for(int i=1;i<=22;i++)
for(int j=1;j<=n;j++){
f[j][i] = f[f[j][i-1]][i-1];
kfc[j][i] = min(kfc[j][i-1], kfc[f[j][i-1]][i-1]);
}
scanf("%d",&t);
while(t -- ){
scanf("%d%d",&x,&y);
printf("%d\n",lca(x, y));
} return 0;
}
// x_x