社区讨论

复杂度是不是假了

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

讨论操作

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

当前回复
7 条
当前快照
1 份
快照标识符
@mii4h28u
此快照首次捕获于
2025/11/28 08:26
3 个月前
此快照最后确认于
2025/11/29 13:25
3 个月前
查看原帖
T 的只剩 3030 分了。
CPP
#include<bits/extc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 2.5e5 + 5;
int n,m,k,tim,idx;
bool imp[maxn];
int st[20][maxn];
int dp[maxn],h[maxn],vec[maxn];
int fa[maxn],son[maxn],top[maxn],rnk[maxn];
int siz[maxn],dep[maxn],dfn[maxn],val[maxn];
class graph
{
    public:
    int head[maxn],idx;
    struct{int v,w,nxt;}e[maxn << 1];
    void adde(int u,int v,int w)
    {
        e[++idx] = {v,w,head[u]};
        head[u] = idx;
    }
}g1,g2;
void dfs1(int u,int pre)
{
    fa[u] = pre,siz[u] = 1;
    dep[u] = dep[pre] + 1;
    for (int i = g1.head[u],v; i; i = g1.e[i].nxt)
    {
        if ((v = g1.e[i].v) == pre)
            continue;
        val[v] = g1.e[i].w;
        dfs1(v,u);
        siz[u] += siz[v];
        if (siz[v] > siz[son[u]])
            son[u] = v;
    }
}
void dfs2(int u,int tp)
{
    dfn[u] = ++tim,rnk[tim] = u;
    top[u] = tp;
    if (son[u])
        dfs2(son[u],tp);
    for (int i = g1.head[u],v; i; i = g1.e[i].nxt)
        if ((v = g1.e[i].v) != fa[u] && v != son[u])
            dfs2(v,v);
}
int lca(int u,int v)
{
    while (top[u] != top[v])
    {
        if (dep[top[u]] < dep[top[v]])
            swap(u,v);
        u = fa[top[u]];
    }
    return dep[u] < dep[v] ? u : v;
}
int que(int l,int r)
{
    if (l > r)
        return inf;
    int k = __lg(r - l + 1);
    return min(st[k][l],st[k][r - (1LL << k) + 1]);
}
int query(int u,int v)
{
    int res = inf;
    while (top[u] != top[v])
    {
        if (dep[top[u]] < dep[top[v]])
            swap(u,v);
        res = min(res,que(dfn[top[u]],dfn[u]));
        u = fa[top[u]];
    }
    if (dep[u] < dep[v])
        swap(u,v);
    res = min(res,que(dfn[v] + 1,dfn[u]));
    return res;
}
bool cmp(int x,int y){return dfn[x] < dfn[y];}
void dfs3(int u)
{
    for (int i = g2.head[u],v; i; i = g2.e[i].nxt)
    {
        v = g2.e[i].v,dfs3(v);
        if (imp[v])
            dp[u] += g2.e[i].w;
        else
            dp[u] += min(g2.e[i].w,dp[v]);
    }
}
void solve()
{
    cin >> k;
    for (int i = 1; i <= k; i++)
        cin >> h[i],imp[h[i]] = 1;
    sort(h + 1,h + k + 1,cmp);
    vec[idx = 1] = 1;
    vec[++idx] = h[1];
    for (int i = 2; i <= k; i++)
    {
        vec[++idx] = h[i];
        vec[++idx] = lca(h[i - 1],h[i]);
    }
    sort(vec + 1,vec + idx + 1,cmp);
    idx = unique(vec + 1,vec + idx + 1) - vec - 1;
    for (int i = 2; i <= idx; i++)
    {
        int anc = lca(vec[i - 1],vec[i]);
        g2.adde(anc,vec[i],query(vec[i],anc));
    }
    dfs3(1),cout << dp[1] << '\n';
    for (int i = 1; i <= idx; i++)
        g2.head[i] = dp[i] = imp[vec[i]] = 0;
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1,u,v,w; i < n; i++)
    {
        cin >> u >> v >> w;
        g1.adde(u,v,w);
        g1.adde(v,u,w);
    }
    dfs1(1,0),dfs2(1,1);
    for (int i = 1; i <= n; i++)
        st[0][i] = val[rnk[i]];
    for (int i = 1; i < 20; i++)
        for (int j = 1; j + (1LL << i) - 1 <= n; j++)
            st[i][j] = min(st[i - 1][j],st[i - 1][j + (1LL << (i - 1))]);
    cin >> m;
    while (m--)
        solve();
    return 0;
}

回复

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

正在加载回复...