树链剖分做法求助
查看原帖
树链剖分做法求助
554746
yiming564楼主2024/4/4 22:16

此题本打算使用树链剖分,不知哪里写错了导致WA 10pts

通过对比 #4 数据,发现错误的输出普遍比期望的输出要小,推测是约束的边界错误,但调不出来,求大佬帮助

#include <bits/extc++.h>

#define inline		__always_inline
#define virtual(x)	((x) + stack)
#define real(x)		((x) - stack)

inline void read(int &x)
{
	char ch = getchar();
	while (!isdigit(ch))	ch = getchar();
	for (x = 0; isdigit(ch); ch = getchar())	x = x * 10 + ch - '0';
}

struct edge_t
{
	int u, v, w;
	inline bool operator<(const edge_t &x) const {	return w > x.w;	}
};

struct simple_edge_t
{
	int v, w;
};

int n, m, q;
int parent[10001];
std::vector<simple_edge_t> graph[10001];

int find(int x)
{
	if (parent[x] != x)
		parent[x] = find(parent[x]);
	return parent[x];
}

void Kruskal()
{
	edge_t edges[50000];
	for (int i = 0; i < m; i++)
		read(edges[i].u), read(edges[i].v), read(edges[i].w);
	std::sort(edges, edges + m);
	for (int i = 1; i <= n; i++)
		parent[i] = i;
	int count = 0;
	for (int i = 0; i < m && count < n - 1; i++)
	{
		if (find(edges[i].u) == find(edges[i].v))
			continue;
		parent[find(edges[i].u)] = find(edges[i].v);
		graph[edges[i].u].push_back({edges[i].v, edges[i].w});
		graph[edges[i].v].push_back({edges[i].u, edges[i].w});
	}
}

struct node_t
{
	node_t *parent;
	node_t *head, *hson;
	int depth, size;
	int start, weight;
};

node_t stack[10001];
int sparse_table[15][10001];

void index()
{
	int level = std::__lg(n);
	for (int i = 1; i <= level; i++)
		for (int j = 0; j + (1 << i) <= n; j++)
			sparse_table[i][j] = std::min(sparse_table[i - 1][j], sparse_table[i - 1][j + (1 << i - 1)]);
}

void build(node_t *v = virtual(1))
{
	v->size = 1;
	v->hson = virtual(0);
	for (auto &&i : graph[real(v)])
	{
		node_t *it = virtual(i.v);
		if (it == v->parent)
			continue;
		it->depth = v->depth + 1;
		it->parent = v;
		it->weight = i.w;
		build(it);
		v->size += it->size;
		if (v->hson->size < it->size)
			v->hson = it;
	}
}

int timestamp = 0;

void decomposition(node_t *v = virtual(1), node_t *head = virtual(1))
{
	if (v == virtual(0))
		return;
	sparse_table[0][timestamp] = v->weight;
	v->start = timestamp++;
	v->head = head;
	decomposition(v->hson, head);
	for (auto &&i : graph[real(v)])
	{
		node_t *it = virtual(i.v);
		if (it == v->parent || it == v->hson)
			continue;
		decomposition(it, it);
	}
}

inline int query_min(int u, int v)
{
	int level = std::__lg(v - u);
	return std::min(sparse_table[level][u], sparse_table[level][v - (1 << level)]);
}

int LCA(node_t *u, node_t *v)
{
	int safe = 0x7fffffff;
	while (u->head != v->head)
	{
		if (u->depth < v->depth)
			std::swap(u, v);
		safe = std::min(safe, query_min(u->head->start, u->start + 1));
		u = u->head->parent;
	}
	if (u == v)
		return safe;
	if (u->depth < v->depth)
		std::swap(u, v);
	safe = std::min(safe, query_min(v->start + 1, u->start + 1));
	return safe;
}

int main()
{
	read(n), read(m);
	Kruskal();
	for (int i = 1; i <= n; i++)
		if (stack[i].size == 0)
		{
			stack[i].parent = virtual(0);
			stack[i].weight = 0x7fffffff;
			build(virtual(i));
			decomposition(virtual(i), virtual(i));
		}
	index();
	read(q);
	int x, y;
	for (int i = 0; i < q; i++)
	{
		read(x), read(y);
		if (find(x) != find(y))
			printf("-1\n");
		else
			printf("%d\n", LCA(virtual(x), virtual(y)));
	}
	return 0;
}
2024/4/4 22:16
加载中...