社区讨论
萌新求助虚树dp WA on#4 8 10
P2495【模板】虚树 / [SDOI2011] 消耗战参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @lo887ovi
- 此快照首次捕获于
- 2023/10/27 14:22 2 年前
- 此快照最后确认于
- 2023/10/27 14:22 2 年前
CPP
#include<bits/stdc++.h>
#define cjb 1145141919810843
#define MAXN 250005
#define ll long long
#define V vshojo
using namespace std;
int n, m;
int a[MAXN];
int vis[MAXN];
struct F_star
{
int cnte = 0, head[MAXN];
struct edge
{
int to, nxt;
int dis;
}e[MAXN << 1];
void adde(int u, int v, int w)
{
e[++cnte].to = v;
e[cnte].dis = w;
e[cnte].nxt = head[u];
head[u] = cnte;
}
}E, vshojo;
ll c[MAXN];
int tcp[MAXN], fa[MAXN], dep[MAXN];
int siz[MAXN], son[MAXN], dfn[MAXN], T;
void dfs1(int u, int f)
{
dfn[u] = ++T;
fa[u] = f; dep[u] = dep[f] + 1; siz[u] = 1;
for(int i = E.head[u]; i; i = E.e[i].nxt)
{
int v = E.e[i].to; if(v == f) continue;
c[v] = min(c[u], 1LL*E.e[i].dis);
dfs1(v, u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
void dfs2(int u, int tup)
{
tcp[u] = tup;
if(son[u]) dfs2(son[u], tup);
for(int i = E.head[u]; i; i = E.e[i].nxt)
{
int v = E.e[i].to;
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
int LCA(int u, int v)
{
while(tcp[u] != tcp[v])
{
if(dep[tcp[u]] >= dep[tcp[v]]) u = fa[tcp[u]];
else v = fa[tcp[v]];
}
return dep[u] < dep[v] ? u : v;
}
bool cmp(int a, int b)
{
return dfn[a] < dfn[b];
}
ll dp(int u)
{
if(vis[u])
{
vis[u] = 0;
return c[u];
}
ll ans = 0;
for(int i = V.head[u]; i; i = V.e[i].nxt)
{
ans += dp(V.e[i].to);
}
return min(c[u], ans);
}
int sta[MAXN], top;
int main()
{
scanf("%d", &n);
for(int i = 1; i < n; i++)
{
int u, v;
ll w;
scanf("%d%d%lld",&u, &v, &w);
E.adde(u, v, w); E.adde(v, u, w);
}
c[1] = cjb;
dfs1(1, 0); dfs2(1, 1);
scanf("%d",&m);
while(m--)
{
int k;
scanf("%d",&k);
for(int i = 1; i <= k; i++)
{
scanf("%d",&a[i]);
vis[a[i]] = 1;
}
sort(a + 1, a + 1 + k, cmp);
top = 0; V.cnte = 0;
int dad = a[1];
for(int i = 1; i <= k; i++)
{
int lc = LCA(a[i], sta[top]);
if(lc != sta[top])
{
while(dfn[lc] < dfn[sta[top-1]])
{
int u = sta[top - 1], v = sta[top];
if(dfn[u] < dfn[dad]) dad = u;
V.adde(u, v, 0);
top--;
}
if(dfn[lc] > dfn[sta[top-1]])
{
V.head[lc] = 0;
V.adde(lc, sta[top], 0);
if(dfn[lc] < dfn[dad]) dad = lc;
sta[top] = lc;
}
else
{
int u = sta[top - 1], v = sta[top];
if(dfn[u] < dfn[dad]) dad = u;
V.adde(u, v, 0);
top--;
}
}
V.head[a[i]] = 0;
sta[++top] = a[i];
}
while(top > 1)
{
int u = sta[top-1], v = sta[top];
if(dfn[u] < dfn[dad]) dad = u;
V.adde(u, v, 0); top--;
}
printf("%lld\n", dp(dad));
}
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...