此题本打算使用树链剖分,不知哪里写错了导致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;
}