10分的倍增LCA求助
查看原帖
10分的倍增LCA求助
141335
qwq2519楼主2021/9/22 11:59
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
#define repg(x) for(register int i(G.head[x]);i;i=G.next[i])
#define bug cout<<"~~~~~~~~~~~~~"<<'\n';
#define bugout(x) cout<<x<<'\n';
using std::cin;
using std::cout;
typedef long long lxl;
template<typename T>
inline T  max( T a, T b) {
	return a > b ? a : b;
}
template<typename T>
inline T  min( T a, T b) {
	return a < b ? a : b;
}

inline char gt() {
	static char buf[1 << 21], *p1 = buf, *p2 = buf;
	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename T>
inline void  read(T &x) {
	register char ch = gt();
	x = 0;
	int w(0);
	while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
	while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
	w ? x = ~(x - 1) : x;
}
template <typename T>
inline void out(T x, char cc) {
	if(x < 0) x = -x, putchar('-');
	char ch[20];
	int num(0);
	while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
	while(num) putchar(ch[num--]);
	putchar(cc);
}
const int N = 1e5 + 79;
const int M = 5e4 + 79;
int n, m, q;
struct graph {
	int head[N], tot, next[N << 1], edge[N << 1], ver[N << 1];
	inline void add(int a, int b, int c) {
		ver[++tot] = b;
		next[tot] = head[a];
		head[a] = tot;
		edge[tot] = c;
	}
} G;
struct edge {
	int x, y, z;
	bool operator <(const edge &rhs) const {
		return z > rhs.z;
	}
} a[M];
int f[N];
inline int find(int x) {
	while(x != f[x]) x = f[x] = f[f[x]];
	return x;
}
int anc[19][N], dep[N], mi[19][N];
inline void dfs(int x) {
	dep[x] = dep[anc[0][x]] + 1;
	repg(x) {
		int y(G.ver[i]), z(G.edge[i]);
		if(y == anc[0][x]) continue;
		anc[0][y] = x;
		mi[0][y] = z;
		dfs(y);
	}
}
inline void init() {
	rep(i, 1, 17)
	rep(j, 1, n) {
		anc[i][j] = anc[i - 1][anc[i - 1][j]];
		mi[i][j] = min(mi[i - 1][j], mi[i - 1][anc[i - 1][j]]);
	}
}

inline int LCA(int x, int y) {
	int ans = 1e9;
	if(dep[x] > dep[y]) std::swap(x, y);
	drp(i, 17, 0) {
		if(dep[anc[i][x]] >= dep[y]) {
			ans = min(ans, mi[i][x]);
			x = anc[i][x];
		}
	}
	if(x == y) return ans;
	drp(i, 17, 0) {
		if(anc[i][x]^anc[i][y]) {
			ans = min(ans, mi[i][x]);
			ans = min(ans, mi[i][y]);
			x = anc[i][x];
			y = anc[i][y];
		}
	}
	ans = min(ans, min(mi[0][y],mi[0][x]));   //!!
	          return ans;
}

int main() {
	read(n);
	read(m);
	rep(i, 1, m) {
		read(a[i].x);
		read(a[i].y);
		read(a[i].z);
	}
	std::sort(a + 1, a + m + 1);

	rep(i, 1, n) {
		f[i] = i;
	}
	rep(i, 1, m) {
		int x(find(a[i].x));
		int y(find(a[i].y));
		if(x == y)continue;
		f[x] = y;
		G.add(a[i].x, a[i].y, a[i].z);
		G.add(a[i].y, a[i].x, a[i].z);
	}
	memset(mi, 0x3f, sizeof mi);
	dfs(1);
	init();
	read(q);
	rep(i, 1, q) {
		int x, y, lca;
		read(x);
		read(y);
//		lca = LCA(x, y);
		if(find(x) != find(y)) {
			out(-1, '\n');
		} else out(LCA(x, y), '\n');
//		out(min(qmin(x, lca), qmin(y, lca)), '\n');
	}
	return 0;
}```
2021/9/22 11:59
加载中...