社区讨论

样例不过玄关求条

P2495【模板】虚树 / [SDOI2011] 消耗战参与者 1已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mm2ucd0s
此快照首次捕获于
2026/02/26 10:25
2 周前
此快照最后确认于
2026/02/27 15:15
2 周前
查看原帖
rt,马蜂优良
CPP
#include<bits/stdc++.h>
#define int long long

using namespace std;

const int MAXN = 1e6 + 1;

int n, cnt, top[MAXN], dfn[MAXN], siz[MAXN], fa[MAXN], seg[MAXN], son[MAXN], dep[MAXN], a[MAXN], len, me[MAXN], k[MAXN], q, m;
struct edge {
    int y, w;
};
vector<edge> c[MAXN], vt[MAXN];
void dfs1(int x, int last) {
    dep[x] = dep[last] + 1;
    fa[x] = last;
    siz[x] = 1;
    for(int i = 0; i < c[x].size(); i++) {
        int y = c[x][i].y;
        if(y == last) {
            continue;
        }
        dfs1(y, x);
        me[y] = min(me[x], c[x][i].w);
        if(siz[y] > siz[son[x]]) {
            son[x] = y;
        }
    }
}
void dfs2(int x, int tp) {
    dfn[x] = ++cnt;
    seg[cnt] = x;
    top[x] = tp;
    if(son[x]) {
        dfs2(son[x], tp);
    }
    for(int i = 0; i < c[x].size(); i++) {
        int y = c[x][i].y;
        if(y == fa[x] || y == son[x]) {
            continue;
        }
        dfs2(y, y);
    }
}
int LCA(int x, int y) {
    while(top[x] != top[y]) {
        if(dep[top[x]] > dep[top[y]]) {
            x = fa[top[x]];
        }
        else {
            y = fa[top[y]];
        }
    }
    return (dep[x] > dep[y] ? y : x);
}
bool cmp(int x, int y) {
    return dfn[x] < dfn[y];
}
void link(int x, int y) {
    vt[x].push_back({y, 0});
}
void bvt() {
    sort(k + 1, k + m + 1, cmp);
    for(int i = 1; i < m; i++) {
        a[++len] = k[i];
        a[++len] = LCA(k[i], k[i + 1]);
    }
    a[++len] = k[m];
    sort(a + 1, a + len + 1, cmp);
    len = unique(a + 1, a + len + 1) - a - 1;
    for(int i = 2; i <= len; i++) {
        link(LCA(a[i], a[i - 1]), a[i]);
    }
}
int dfsdp(int x) {
    if(vt[x].size() == 0) {
        return me[x];
    }
    int res = 0;
    for(int i = 0; i < vt[x].size(); i++) {
        int y = vt[x][i].y;
        res += dfsdp(y);
    }
    vt[x].clear();
    return min(res, me[x]);
}

signed main() {
    cin >> n;
    for(int i = 1, x, y, w; i < n; i++) {
        cin >> x >> y >> w;
        c[x].push_back({y, w});
        c[y].push_back({x, w});
    }
    dfs1(1, 0);
    dfs2(1, 1);
    cin >> q;
    while(q--) {
        me[1] = 1e18;
        len = 0;
        cin >> m;
        for(int i = 1; i <= m; i++) {
            cin >> k[i];
        }
        bvt();
        cout << dfsdp(1, -1) << "\n";
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...