萌新树剖0pts过hack和样例悬赏一关注求调
查看原帖
萌新树剖0pts过hack和样例悬赏一关注求调
610557
shinzanmonoszm 妹妹楼主2023/1/20 22:50
#include<iostream>
#include<algorithm>
#include<vector>
const int sz = 1e4 + 10;
const int lgsz = std::__lg(sz) + 1;
int arr[sz], rnk[sz], n, m, f[lgsz][sz];
struct Edge {
    int u, v, w;
    bool operator<(const Edge &a) const {
        return w > a.w;
    }
} Graph[sz * 6];
struct edge {
    int nxt, to, w;
} graph[sz << 1];
int hpp, head[sz];
void addEdge(int from, int to, int w) {
    graph[++hpp] = edge{head[from], to, w};
    head[from] = hpp;
}
struct UFS {
    std::vector<int> fa, ssz;
    void clear(int n) {
        fa.assign(n + 1, 0), ssz.assign(n + 1, 1);
        for (int i = 1; i <= n; i++) fa[i] = i;
    }
    int find(int u) {
        if (fa[u] == u) return u;
        return fa[u] = find(fa[u]);
    }
    bool merge(int u, int v) {
        int fu = find(u), fv = find(v);
        if (fu == fv) return false;
        if (ssz[fu] > ssz[fv]) std::swap(fu, fv);
        fa[fu] = fv, ssz[fv] += ssz[fu];
        return true;
    }
} ufs, graphChecker;
void kruskal() {
    std::sort(Graph + 1, Graph + m + 1);
    for (int i = 1; i <= m; i++) {
        int u = Graph[i].u, v = Graph[i].v;
        if (!ufs.merge(u, v)) continue;
        addEdge(u, v, Graph[i].w);
        addEdge(v, u, Graph[i].w);
    }
}
int hson[sz], ssz[sz], dfn[sz], dep[sz], dpp, top[sz], fa[sz];
void buildDFS(int u, int fau) {
    dep[u] = dep[fau] + 1, ssz[u] = 1, fa[u] = fau;
    for (int p = head[u]; p; p = graph[p].nxt) {
        int v = graph[p].to;
        arr[v] = graph[p].w;
        if (v == fau) continue;
        buildDFS(v, u);
        ssz[u] += ssz[v];
        if (ssz[v] > ssz[hson[u]]) hson[u] = v;
    } 
}
void chainDFS(int u, int t) {
    top[u] = t, dfn[u] = ++dpp, rnk[dpp] = u;
    if (!hson[u]) return;
    chainDFS(hson[u], t);
    for (int p = head[u]; p; p = graph[p].nxt) {
        int v = graph[p].to;
        if (v == hson[u] || v == fa[u]) continue;
        chainDFS(v, v);
    }
}
int queryMin(int l, int r) {
    int lg = std::__lg(r - l + 1);
    return std::min(f[lg][l], f[lg][r - (1 << lg) + 1]);
}
int query(int u, int v) {
    int res = 0x3fffffff;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) std::swap(u, v);
        res = std::min(res, queryMin(dfn[top[u]], dfn[u]));
        u = fa[top[u]];
    }
    if (dfn[u] > dfn[v]) std::swap(u, v);
    res = std::min(res, queryMin(dfn[u], dfn[v]));
    return res;
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n >> m;
    ufs.clear(n), graphChecker.clear(n);
    for (int i = 1; i <= m; i++) {
        std::cin >> Graph[i].u >> Graph[i].v >> Graph[i].w;
        graphChecker.merge(Graph[i].u, Graph[i].v);
    }
    for (int i = 1; i <= n; i++)
        if (graphChecker.merge(1, i)) 
            Graph[++m] = Edge{1, i, -1};
    kruskal();
    buildDFS(1, 0);
    arr[1] = 0x3fffffff;
    chainDFS(1, 1);
    for (int i = 1; i <= n; i++) 
        f[0][i] = arr[rnk[i]];
    for (int i = 1; i <= std::__lg(n); i++) 
        for (int j = 1; j + (1 << i) - 1 <= n; j++) 
            f[i][j] = std::min(f[i - 1][j], f[i - 1][j + (1 << i - 1)]);
    int q;
    std::cin >> q;
    while (q--) {
        int u, v;
        std::cin >> u >> v;
        std::cout << query(u, v) << "\n";
    }
    return 0;
}
2023/1/20 22:50
加载中...