求助虚树 TLE
查看原帖
求助虚树 TLE
726992
ccxswl楼主2024/8/9 14:56

萌新刚学虚树,用的 二次排序+LCA 建树,在第 5 6 7 9 TLE

#include <bits/stdc++.h>

using namespace std;

using ubt = long long;

inline int read() {
    int s = 0, w = 1;
    char c = getchar();
    while (!isdigit(c)) {
        if (c == '-') w = -w;
        c = getchar();
    }
    while (isdigit(c)) {
        s = s * 10 + c - 48;
        c = getchar();
    }
    return s * w;
}
#define end_ putchar('\n')
#define spc_ putchar(' ')
void write(ubt x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + 48);
}

const int maxN = 2.5e5 + 7;

int n;
int head[maxN], tot;
struct edge {
    int ls, to, w;
} e[maxN << 1];
void add(int u, int v, int w) {
    e[++tot] = {head[u], v, w};
    head[u] = tot;
}

int dfn[maxN], cnt;
int get(int x, int y) {
    return dfn[x] < dfn[y] ? x : y;
}
int g[30][maxN];
int a[maxN];
int fa[maxN];
void dfs(int x, int f) {
    fa[x] = f;
    dfn[x] = ++cnt;
    g[0][dfn[x]] = f;
    for (int i = head[x]; i; i = e[i].ls) {
        int to = e[i].to;
        if (to == f) continue;
        a[to] = e[i].w;
        dfs(to, x);
    }
}
int lca(int x, int y) {
    if (x == y) return x;
    x = dfn[x], y = dfn[y];
    if (x > y) swap(x, y);
    x++;
    int t = __lg(y - x + 1);
    return get(g[t][x], g[t][y - (1 << t) + 1]);
}

int m;
struct ques {
    int k;
    vector<int> qu;
} q[maxN << 1];
int G[maxN << 1], Gg[maxN << 1], len;
vector<int> E[maxN];
bool is[maxN];

void change(int x, int H) {
    a[H] = min(a[H], a[x]);
    if (fa[x] && !is[fa[x]])
        change(fa[x], H);
}

ubt dp[maxN];
void calc(int x, int f) {
    dp[x] = 0;
    for (auto to : E[x]) {
        if (to == f) continue;
        calc(to, x);
        if (is[to])
            dp[x] += a[to];
        else
            dp[x] += min(dp[to], 1ll * a[to]);
    }
}

int main() {
    n = read();
    for (int i = 1; i < n; i++) {
        int x = read(), y = read(), z = read();
        add(x, y, z);
        add(y, x, z);
    }
    dfs(1, 0);
    for (int t = 1; t <= 20; t++)
        for (int i = 1; i + (1 << t) - 1 <= n; i++)
            g[t][i] = get(g[t - 1][i], g[t - 1][i + (1 << (t - 1))]);

    m = read();
    for (int i = 1; i <= m; i++) {
        q[i].k = read();
        for (int j = 1; j <= q[i].k; j++) {
            int o = read();
            q[i].qu.push_back(o);
            G[++G[0]] = o;
        }
    }
    /*
    16
    1 2 1
    2 3 1
    2 4 1
    4 5 1
    4 6 1
    1 7 1
    7 8 1
    7 9 1
    7 10 1
    8 11 1
    11 12 1
    11 13 1
    13 14 1
    14 15 1
    14 16 1
    1
    7 3 4 5 6 7 12 14
    */

    // cerr << "G : ";
    // for (int i = 1; i <= G[0]; i++)
    //     cerr << G[i] << ' ';
    // cerr << '\n';

    auto cmp = [](int a, int b) {
        return dfn[a] < dfn[b];
    };
    sort(G + 1, G + G[0] + 1, cmp);
    G[0] = unique(G + 1, G + G[0] + 1) - G - 1;
    Gg[++len] = 1;
    for (int i = 1; i < G[0]; i++) {
        Gg[++len] = G[i];
        Gg[++len] = lca(G[i], G[i + 1]);
    }
    Gg[++len] = G[G[0]];
    sort(Gg + 1, Gg + len + 1, cmp);
    len = unique(Gg + 1, Gg + len + 1) - Gg - 1;
    for (int i = 1; i < len; i++) {
        int lc = lca(Gg[i], Gg[i + 1]);
        is[lc] = is[Gg[i + 1]] = true;
        E[lc].push_back(Gg[i + 1]);
    }
    // for (int i = 1; i <= n; i++) {
    //     cerr << i << " : ";
    //     for (int j : E[i])
    //         cerr << j << ' ';
    //     cerr << '\n';
    // }

    for (int i = 1; i <= n; i++)
        if (is[i])
            change(i, i);
    for (int i = 1; i <= n; i++)
        is[i] = false;
    
    for (int i = 1; i <= m; i++) {
        for (auto j : q[i].qu)
            is[j] = true;
        calc(1, 0);
        write(dp[1]), end_;
        for (auto j : q[i].qu)
            is[j] = false;
    }
}
                
2024/8/9 14:56
加载中...