倍增LCA+Kruscal生成树,样例过不了,求调
查看原帖
倍增LCA+Kruscal生成树,样例过不了,求调
334935
youyi2008楼主2022/8/3 21:09
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10001;
int n, m, q;
vector<pair<int, int>> g[maxn];
namespace KRUSCAL
{
	struct node
	{
		int l, r;
		int v;
	};
	int fa[maxn];
	vector<node> ve;
	bool cmp(node x, node y)
	{
		return x.v > y.v;
	}
	void init()
	{
		for (int i = 1; i <= n; i++)
			fa[i] = i;
	}
	int find(int x)
	{
		if (fa[x] == x)
			return x;
		return fa[x] = find(fa[x]);
	}
	void add(node k)
	{
		g[k.l].push_back({k.v, k.r});
		g[k.r].push_back({k.v, k.l});
	}
	void merge(node k)
	{
		int x = find(k.l), y = find(k.r);
		if (x != y)
			fa[x] = y, add(k);
	}
	void kruscal()
	{
		init();
		sort(ve.begin(), ve.end(), cmp);
		for (auto ed : ve)
			merge(ed);
	}
}
using KRUSCAL::find;
using KRUSCAL::kruscal;
using KRUSCAL::ve;
namespace LCA
{
	int w[maxn][31], dep[maxn], fa[maxn][31];
	void dfs(int x, int f)
	{
		fa[x][0] = f;
		dep[x] = dep[fa[x][0]] + 1;
		for (int i = 1; i < 31; i++)
		{
			fa[x][i] = fa[fa[x][i - 1]][i - 1];
			// w[x][i] = w[fa[x][i - 1]][i - 1] + w[x][i - 1];
			w[x][i] = min(w[fa[x][i - 1]][i - 1], w[x][i - 1]);
		}
		for (auto ed : g[x])
		{
			if (ed.second == f)
				continue;
			w[ed.second][0] = ed.first;
			dfs(ed.second, x);
		}
	}
	int lca(int x, int y)
	{
		if (dep[x] > dep[y])
			swap(x, y);
		int tmp = dep[y] - dep[x], ans = 0;
		for (int i = 0; tmp; i++, tmp >>= 1)
			if (tmp & 1)
				ans = min(ans, w[y][i]), y = fa[y][i];
		if (x == y)
			return ans;
		for (int j = 30; j >= 0 && x != y; j--)
			if (fa[x][j] != fa[y][j])
				ans = min(ans, min(w[x][j], w[y][j])),
				x = fa[x][j],
				y = fa[y][j];
		ans = min(ans, min(w[x][0], w[y][0]));
		return ans;
	}
}
using LCA::dfs;
using LCA::fa;
using LCA::lca;
using LCA::w;
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int x, y, z;
		cin >> x >> y >> z;
		ve.push_back({x, y, z});
	}
	kruscal();
	memset(w, 0x3f, sizeof w);
	dfs(1, 0);
	cin >> q;
	for (int i = 1; i <= q; i++)
	{
		int x, y;
		cin >> x >> y;
		if (find(x) != find(y))
			cout << "-1" << endl;
		else
			cout << lca(x, y) << endl;
	}
	system("pause");
}
2022/8/3 21:09
加载中...