警示后人,如果你kruskal,但是只对了#1,2,3
查看原帖
警示后人,如果你kruskal,但是只对了#1,2,3
1165228
o_CIHL楼主2024/11/12 23:40

看下面的代码,是的,是错误的。仔细看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 
2024/11/12 23:40
加载中...