Kruskal 重构树 输入超时求调
查看原帖
Kruskal 重构树 输入超时求调
176205
uncesspath楼主2023/10/25 17:29

代码:

#include <iostream>
#include <algorithm>
#include <vector>

using std::cin;
using std::cout;

const int N = 10000 + 10;

struct edge
{
    int u, v, w;
    bool operator<(const edge& b) const { return w > b.w; }
};

std::vector<int> tr[N << 1];
edge e[50010];
int n, m, q;
int f[N << 1], w[N << 1];
int dep[N << 1], fa[N << 1], siz[N << 1], son[N << 1], top[N << 1];

void dfs1(int u)
{
    siz[u] = 1;
    for (auto v : tr[u])
    {
        if (v == fa[u])
            continue;
        fa[v] = u;
        dep[v] = dep[u] + 1;
        dfs1(v);
        siz[u] += siz[v];
        son[u] = siz[son[u]] > siz[v] ? son[u] : v;
    }
}

void dfs2(int u)
{
    if (u == 2 * n - 1)
        top[u] = u;
    if (son[u])
    {
        top[son[u]] = top[u];
        dfs2(son[u]);
    }
    for (auto v : tr[u])
    {
        if (v == fa[u] || v == son[u])
            continue;
        top[v] = v;
        dfs2(v);
    }
}

int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }

void Kruskal()
{
    std::sort(e + 1, e + 1 + m);
    for (int i = 1; i <= 2 * n - 1; i++)
        f[i] = i;
    int tot = n;
    for (auto ed : e)
    {
        int x = find(ed.u), y = find(ed.v);
        if (x == y)
            continue;
        tot++;
        f[x] = f[y] = f[tot];
        tr[tot].push_back(x);
        tr[tot].push_back(y);
        tr[x].push_back(tot);
        tr[y].push_back(tot);
        w[tot] = ed.w;
        if (tot == 2 * n - 1)
            break;
    }
    for (int i = 1; i <= n; i++)
    {
        int f = find(i);
        if (!top[f])
        {
            dfs1(f);
            dfs2(f);
        }
    }
}

int LCA(int x, int y)
{
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            std::swap(x, y);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        std::swap(x, y);
    return x;
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;
    for (int i = 1; i <= m; i++)
        cin >> e[i].u >> e[i].v >> e[i].w;
    Kruskal();
    cin >> q;
    while (q--)
    {
        int x, y;
        cin >> x >> y;
        if (find(x) != find(y))
        {
            cout << "-1\n";
            continue;
        }
        cout << w[LCA(x, y)] << '\n';
    }
    return 0;
}

把 #14 在本地跑了一下发现是输入超时,蒟蒻疑惑。

2023/10/25 17:29
加载中...