题目链接
题意:给定一个图,要求每次询问两点,求出这两点间路径最大危险系数最小
思路:先求最小生成树,在生成树上每次询问求LCT就可以了,利用树链剖分求解
代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) const int N = 50005; const int M = 100005; int dep[N], sz[N], son[N], fa[N], top[N], id[N], idx, val[N]; int n, m, parent[N]; vector<int> g[N]; int find(int x) { return x == parent[x] ? x : parent[x] = find(parent[x]); } struct Edge { int u, v, val; bool ismst; void read() { scanf("%d%d%d", &u, &v, &val); ismst = false; } } e[M]; bool cmp(Edge a, Edge b) { return a.val < b.val; } void dfs1(int u, int f, int d) { dep[u] = d; sz[u] = 1; son[u] = 0; fa[u] = f; for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if (v == f) continue; dfs1(v, u, d + 1); sz[u] += sz[v]; if (sz[son[u]] < sz[v]) son[u] = v; } } void dfs2(int u, int tp) { top[u] = tp; id[u] = ++idx; if (son[u]) dfs2(son[u], tp); for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if (v == fa[u] || v == son[u]) continue; dfs2(v, v); } } struct Node { int l, r, v; } node[4 * N]; void pushup(int x) { node[x].v = max(node[lson(x)].v, node[rson(x)].v); } void build(int l, int r, int x = 0) { node[x].l = l; node[x].r = r; node[x].v = 0; if (l == r) { node[x].v = val[l]; return; } int mid = (l + r) / 2; build(l, mid, lson(x)); build(mid + 1, r, rson(x)); pushup(x); } int query(int l, int r, int x = 0) { if (node[x].l >= l && node[x].r <= r) { return node[x].v; } int mid = (node[x].l + node[x].r) / 2; int ans = 0; if (l <= mid) ans = max(ans, query(l, r, lson(x))); if (r > mid) ans = max(ans, query(l, r, rson(x))); return ans; } int gao(int u, int v) { int tp1 = top[u], tp2 = top[v]; int ans = 0; while (tp1 != tp2) { if (dep[tp1] < dep[tp2]) { swap(tp1, tp2); swap(u, v); } ans = max(ans, query(id[tp1], id[u])); u = fa[tp1]; tp1 = top[u]; } if (u == v) return ans; if (dep[u] > dep[v]) swap(u, v); ans = max(ans, query(id[son[u]], id[v])); return ans; } int main() { int bo = 0; while (~scanf("%d%d", &n, &m)) { if (bo) printf("\n"); else bo = 1; idx = -1; for (int i = 1; i <= n; i++) { parent[i] = i; g[i].clear(); } for (int i = 0; i < m; i++) e[i].read(); sort(e, e + m, cmp); for (int i = 0; i < m; i++) { int pu = find(e[i].u); int pv = find(e[i].v); if (pu != pv) { g[e[i].u].push_back(e[i].v); g[e[i].v].push_back(e[i].u); e[i].ismst = true; parent[pu] = pv; } } dfs1(1, -1, 1); dfs2(1, 1); for (int i = 0; i < m; i++) { if (!e[i].ismst) continue; if (dep[e[i].u] < dep[e[i].v]) swap(e[i].u, e[i].v); val[id[e[i].u]] = e[i].val; } build(1, idx); int q; scanf("%d", &q); int a, b; while (q--) { scanf("%d%d", &a, &b); printf("%d\n", gao(a, b)); } } return 0; }